LCOV - code coverage report
Current view: top level - dom/base - nsContentPermissionHelper.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 395 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 82 0.0 %
Legend: Lines: hit not hit

          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
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include <map>
       8             : #ifdef MOZ_WIDGET_GONK
       9             : #include "GonkPermission.h"
      10             : #endif // MOZ_WIDGET_GONK
      11             : #include "nsCOMPtr.h"
      12             : #include "nsIDOMElement.h"
      13             : #include "nsIPrincipal.h"
      14             : #include "mozilla/dom/ContentChild.h"
      15             : #include "mozilla/dom/ContentParent.h"
      16             : #include "mozilla/dom/Element.h"
      17             : #include "mozilla/dom/Event.h"
      18             : #include "mozilla/dom/PContentPermission.h"
      19             : #include "mozilla/dom/PermissionMessageUtils.h"
      20             : #include "mozilla/dom/PContentPermissionRequestParent.h"
      21             : #include "mozilla/dom/ScriptSettings.h"
      22             : #include "mozilla/dom/TabChild.h"
      23             : #include "mozilla/dom/TabParent.h"
      24             : #include "mozilla/Unused.h"
      25             : #include "nsComponentManagerUtils.h"
      26             : #include "nsArrayUtils.h"
      27             : #include "nsIMutableArray.h"
      28             : #include "nsContentPermissionHelper.h"
      29             : #include "nsJSUtils.h"
      30             : #include "nsISupportsPrimitives.h"
      31             : #include "nsServiceManagerUtils.h"
      32             : #include "nsIDocument.h"
      33             : #include "nsIDOMEvent.h"
      34             : #include "nsWeakPtr.h"
      35             : 
      36             : using mozilla::Unused;          // <snicker>
      37             : using namespace mozilla::dom;
      38             : using namespace mozilla;
      39             : 
      40             : #define kVisibilityChange "visibilitychange"
      41             : 
      42             : class VisibilityChangeListener final : public nsIDOMEventListener
      43             : {
      44             : public:
      45             :   NS_DECL_ISUPPORTS
      46             :   NS_DECL_NSIDOMEVENTLISTENER
      47             : 
      48             :   explicit VisibilityChangeListener(nsPIDOMWindowInner* aWindow);
      49             : 
      50             :   void RemoveListener();
      51             :   void SetCallback(nsIContentPermissionRequestCallback* aCallback);
      52             :   already_AddRefed<nsIContentPermissionRequestCallback> GetCallback();
      53             : 
      54             : private:
      55           0 :   virtual ~VisibilityChangeListener() {}
      56             : 
      57             :   nsWeakPtr mWindow;
      58             :   nsCOMPtr<nsIContentPermissionRequestCallback> mCallback;
      59             : };
      60             : 
      61           0 : NS_IMPL_ISUPPORTS(VisibilityChangeListener, nsIDOMEventListener)
      62             : 
      63           0 : VisibilityChangeListener::VisibilityChangeListener(nsPIDOMWindowInner* aWindow)
      64             : {
      65           0 :   MOZ_ASSERT(aWindow);
      66             : 
      67           0 :   mWindow = do_GetWeakReference(aWindow);
      68           0 :   nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
      69           0 :   if (doc) {
      70           0 :     doc->AddSystemEventListener(NS_LITERAL_STRING(kVisibilityChange),
      71             :                                 /* listener */ this,
      72             :                                 /* use capture */ true,
      73           0 :                                 /* wants untrusted */ false);
      74             :   }
      75             : 
      76           0 : }
      77             : 
      78             : NS_IMETHODIMP
      79           0 : VisibilityChangeListener::HandleEvent(nsIDOMEvent* aEvent)
      80             : {
      81           0 :   nsAutoString type;
      82           0 :   aEvent->GetType(type);
      83           0 :   if (!type.EqualsLiteral(kVisibilityChange)) {
      84           0 :     return NS_ERROR_FAILURE;
      85             :   }
      86             : 
      87             :   nsCOMPtr<nsIDocument> doc =
      88           0 :     do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget());
      89           0 :   MOZ_ASSERT(doc);
      90             : 
      91           0 :   if (mCallback) {
      92           0 :     mCallback->NotifyVisibility(!doc->Hidden());
      93             :   }
      94             : 
      95           0 :   return NS_OK;
      96             : }
      97             : 
      98             : void
      99           0 : VisibilityChangeListener::RemoveListener()
     100             : {
     101           0 :   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(mWindow);
     102           0 :   if (!window) {
     103           0 :     return;
     104             :   }
     105             : 
     106           0 :   nsCOMPtr<EventTarget> target = do_QueryInterface(window->GetExtantDoc());
     107           0 :   if (target) {
     108           0 :     target->RemoveSystemEventListener(NS_LITERAL_STRING(kVisibilityChange),
     109             :                                       /* listener */ this,
     110           0 :                                       /* use capture */ true);
     111             :   }
     112             : }
     113             : 
     114             : void
     115           0 : VisibilityChangeListener::SetCallback(nsIContentPermissionRequestCallback *aCallback)
     116             : {
     117           0 :   mCallback = aCallback;
     118           0 : }
     119             : 
     120             : already_AddRefed<nsIContentPermissionRequestCallback>
     121           0 : VisibilityChangeListener::GetCallback()
     122             : {
     123           0 :   nsCOMPtr<nsIContentPermissionRequestCallback> callback = mCallback;
     124           0 :   return callback.forget();
     125             : }
     126             : 
     127             : namespace mozilla {
     128             : namespace dom {
     129             : 
     130             : class ContentPermissionRequestParent : public PContentPermissionRequestParent
     131             : {
     132             :  public:
     133             :   ContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
     134             :                                  Element* element,
     135             :                                  const IPC::Principal& principal);
     136             :   virtual ~ContentPermissionRequestParent();
     137             : 
     138             :   bool IsBeingDestroyed();
     139             : 
     140             :   nsCOMPtr<nsIPrincipal> mPrincipal;
     141             :   nsCOMPtr<Element> mElement;
     142             :   RefPtr<nsContentPermissionRequestProxy> mProxy;
     143             :   nsTArray<PermissionRequest> mRequests;
     144             : 
     145             :  private:
     146             :   virtual mozilla::ipc::IPCResult Recvprompt();
     147             :   virtual mozilla::ipc::IPCResult RecvNotifyVisibility(const bool& aIsVisible);
     148             :   virtual mozilla::ipc::IPCResult RecvDestroy();
     149             :   virtual void ActorDestroy(ActorDestroyReason why);
     150             : };
     151             : 
     152           0 : ContentPermissionRequestParent::ContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
     153             :                                                                Element* aElement,
     154           0 :                                                                const IPC::Principal& aPrincipal)
     155             : {
     156           0 :   MOZ_COUNT_CTOR(ContentPermissionRequestParent);
     157             : 
     158           0 :   mPrincipal = aPrincipal;
     159           0 :   mElement   = aElement;
     160           0 :   mRequests  = aRequests;
     161           0 : }
     162             : 
     163           0 : ContentPermissionRequestParent::~ContentPermissionRequestParent()
     164             : {
     165           0 :   MOZ_COUNT_DTOR(ContentPermissionRequestParent);
     166           0 : }
     167             : 
     168             : mozilla::ipc::IPCResult
     169           0 : ContentPermissionRequestParent::Recvprompt()
     170             : {
     171           0 :   mProxy = new nsContentPermissionRequestProxy();
     172           0 :   if (NS_FAILED(mProxy->Init(mRequests, this))) {
     173           0 :     mProxy->Cancel();
     174             :   }
     175           0 :   return IPC_OK();
     176             : }
     177             : 
     178             : mozilla::ipc::IPCResult
     179           0 : ContentPermissionRequestParent::RecvNotifyVisibility(const bool& aIsVisible)
     180             : {
     181           0 :   if (!mProxy) {
     182           0 :     return IPC_FAIL_NO_REASON(this);
     183             :   }
     184           0 :   mProxy->NotifyVisibility(aIsVisible);
     185           0 :   return IPC_OK();
     186             : }
     187             : 
     188             : mozilla::ipc::IPCResult
     189           0 : ContentPermissionRequestParent::RecvDestroy()
     190             : {
     191           0 :   Unused << PContentPermissionRequestParent::Send__delete__(this);
     192           0 :   return IPC_OK();
     193             : }
     194             : 
     195             : void
     196           0 : ContentPermissionRequestParent::ActorDestroy(ActorDestroyReason why)
     197             : {
     198           0 :   if (mProxy) {
     199           0 :     mProxy->OnParentDestroyed();
     200             :   }
     201           0 : }
     202             : 
     203             : bool
     204           0 : ContentPermissionRequestParent::IsBeingDestroyed()
     205             : {
     206             :   // When ContentParent::MarkAsDead() is called, we are being destroyed.
     207             :   // It's unsafe to send out any message now.
     208           0 :   ContentParent* contentParent = static_cast<ContentParent*>(Manager());
     209           0 :   return !contentParent->IsAlive();
     210             : }
     211             : 
     212           0 : NS_IMPL_ISUPPORTS(ContentPermissionType, nsIContentPermissionType)
     213             : 
     214           0 : ContentPermissionType::ContentPermissionType(const nsACString& aType,
     215             :                                              const nsACString& aAccess,
     216           0 :                                              const nsTArray<nsString>& aOptions)
     217             : {
     218           0 :   mType = aType;
     219           0 :   mAccess = aAccess;
     220           0 :   mOptions = aOptions;
     221           0 : }
     222             : 
     223           0 : ContentPermissionType::~ContentPermissionType()
     224             : {
     225           0 : }
     226             : 
     227             : NS_IMETHODIMP
     228           0 : ContentPermissionType::GetType(nsACString& aType)
     229             : {
     230           0 :   aType = mType;
     231           0 :   return NS_OK;
     232             : }
     233             : 
     234             : NS_IMETHODIMP
     235           0 : ContentPermissionType::GetAccess(nsACString& aAccess)
     236             : {
     237           0 :   aAccess = mAccess;
     238           0 :   return NS_OK;
     239             : }
     240             : 
     241             : NS_IMETHODIMP
     242           0 : ContentPermissionType::GetOptions(nsIArray** aOptions)
     243             : {
     244           0 :   NS_ENSURE_ARG_POINTER(aOptions);
     245             : 
     246           0 :   *aOptions = nullptr;
     247             : 
     248             :   nsresult rv;
     249             :   nsCOMPtr<nsIMutableArray> options =
     250           0 :     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
     251           0 :   NS_ENSURE_SUCCESS(rv, rv);
     252             : 
     253             :   // copy options into JS array
     254           0 :   for (uint32_t i = 0; i < mOptions.Length(); ++i) {
     255             :     nsCOMPtr<nsISupportsString> isupportsString =
     256           0 :       do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
     257           0 :     NS_ENSURE_SUCCESS(rv, rv);
     258             : 
     259           0 :     rv = isupportsString->SetData(mOptions[i]);
     260           0 :     NS_ENSURE_SUCCESS(rv, rv);
     261             : 
     262           0 :     rv = options->AppendElement(isupportsString, false);
     263           0 :     NS_ENSURE_SUCCESS(rv, rv);
     264             :   }
     265             : 
     266           0 :   options.forget(aOptions);
     267           0 :   return NS_OK;
     268             : }
     269             : 
     270             : // nsContentPermissionUtils
     271             : 
     272             : /* static */ uint32_t
     273           0 : nsContentPermissionUtils::ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
     274             :                                                           nsIMutableArray* aDesArray)
     275             : {
     276           0 :   uint32_t len = aSrcArray.Length();
     277           0 :   for (uint32_t i = 0; i < len; i++) {
     278             :     RefPtr<ContentPermissionType> cpt =
     279           0 :       new ContentPermissionType(aSrcArray[i].type(),
     280           0 :                                 aSrcArray[i].access(),
     281           0 :                                 aSrcArray[i].options());
     282           0 :     aDesArray->AppendElement(cpt, false);
     283             :   }
     284           0 :   return len;
     285             : }
     286             : 
     287             : /* static */ uint32_t
     288           0 : nsContentPermissionUtils::ConvertArrayToPermissionRequest(nsIArray* aSrcArray,
     289             :                                                           nsTArray<PermissionRequest>& aDesArray)
     290             : {
     291           0 :   uint32_t len = 0;
     292           0 :   aSrcArray->GetLength(&len);
     293           0 :   for (uint32_t i = 0; i < len; i++) {
     294           0 :     nsCOMPtr<nsIContentPermissionType> cpt = do_QueryElementAt(aSrcArray, i);
     295           0 :     nsAutoCString type;
     296           0 :     nsAutoCString access;
     297           0 :     cpt->GetType(type);
     298           0 :     cpt->GetAccess(access);
     299             : 
     300           0 :     nsCOMPtr<nsIArray> optionArray;
     301           0 :     cpt->GetOptions(getter_AddRefs(optionArray));
     302           0 :     uint32_t optionsLength = 0;
     303           0 :     if (optionArray) {
     304           0 :       optionArray->GetLength(&optionsLength);
     305             :     }
     306           0 :     nsTArray<nsString> options;
     307           0 :     for (uint32_t j = 0; j < optionsLength; ++j) {
     308           0 :       nsCOMPtr<nsISupportsString> isupportsString = do_QueryElementAt(optionArray, j);
     309           0 :       if (isupportsString) {
     310           0 :         nsString option;
     311           0 :         isupportsString->GetData(option);
     312           0 :         options.AppendElement(option);
     313             :       }
     314             :     }
     315             : 
     316           0 :     aDesArray.AppendElement(PermissionRequest(type, access, options));
     317             :   }
     318           0 :   return len;
     319             : }
     320             : 
     321             : static std::map<PContentPermissionRequestParent*, TabId>&
     322           0 : ContentPermissionRequestParentMap()
     323             : {
     324           0 :   MOZ_ASSERT(NS_IsMainThread());
     325           0 :   static std::map<PContentPermissionRequestParent*, TabId> sPermissionRequestParentMap;
     326           0 :   return sPermissionRequestParentMap;
     327             : }
     328             : 
     329             : static std::map<PContentPermissionRequestChild*, TabId>&
     330           0 : ContentPermissionRequestChildMap()
     331             : {
     332           0 :   MOZ_ASSERT(NS_IsMainThread());
     333           0 :   static std::map<PContentPermissionRequestChild*, TabId> sPermissionRequestChildMap;
     334           0 :   return sPermissionRequestChildMap;
     335             : }
     336             : 
     337             : /* static */ nsresult
     338           0 : nsContentPermissionUtils::CreatePermissionArray(const nsACString& aType,
     339             :                                                 const nsACString& aAccess,
     340             :                                                 const nsTArray<nsString>& aOptions,
     341             :                                                 nsIArray** aTypesArray)
     342             : {
     343           0 :   nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
     344             :   RefPtr<ContentPermissionType> permType = new ContentPermissionType(aType,
     345             :                                                                        aAccess,
     346           0 :                                                                        aOptions);
     347           0 :   types->AppendElement(permType, false);
     348           0 :   types.forget(aTypesArray);
     349             : 
     350           0 :   return NS_OK;
     351             : }
     352             : 
     353             : /* static */ PContentPermissionRequestParent*
     354           0 : nsContentPermissionUtils::CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
     355             :                                                                Element* element,
     356             :                                                                const IPC::Principal& principal,
     357             :                                                                const TabId& aTabId)
     358             : {
     359             :   PContentPermissionRequestParent* parent =
     360           0 :     new ContentPermissionRequestParent(aRequests, element, principal);
     361           0 :   ContentPermissionRequestParentMap()[parent] = aTabId;
     362             : 
     363           0 :   return parent;
     364             : }
     365             : 
     366             : /* static */ nsresult
     367           0 : nsContentPermissionUtils::AskPermission(nsIContentPermissionRequest* aRequest,
     368             :                                         nsPIDOMWindowInner* aWindow)
     369             : {
     370           0 :   MOZ_ASSERT(!aWindow || aWindow->IsInnerWindow());
     371           0 :   NS_ENSURE_STATE(aWindow && aWindow->IsCurrentInnerWindow());
     372             : 
     373             :   // for content process
     374           0 :   if (XRE_IsContentProcess()) {
     375             : 
     376             :     RefPtr<RemotePermissionRequest> req =
     377           0 :       new RemotePermissionRequest(aRequest, aWindow);
     378             : 
     379           0 :     MOZ_ASSERT(NS_IsMainThread()); // IPC can only be execute on main thread.
     380             : 
     381           0 :     TabChild* child = TabChild::GetFrom(aWindow->GetDocShell());
     382           0 :     NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
     383             : 
     384           0 :     nsCOMPtr<nsIArray> typeArray;
     385           0 :     nsresult rv = aRequest->GetTypes(getter_AddRefs(typeArray));
     386           0 :     NS_ENSURE_SUCCESS(rv, rv);
     387             : 
     388           0 :     nsTArray<PermissionRequest> permArray;
     389           0 :     ConvertArrayToPermissionRequest(typeArray, permArray);
     390             : 
     391           0 :     nsCOMPtr<nsIPrincipal> principal;
     392           0 :     rv = aRequest->GetPrincipal(getter_AddRefs(principal));
     393           0 :     NS_ENSURE_SUCCESS(rv, rv);
     394             : 
     395           0 :     req->IPDLAddRef();
     396           0 :     ContentChild::GetSingleton()->SendPContentPermissionRequestConstructor(
     397             :       req,
     398             :       permArray,
     399           0 :       IPC::Principal(principal),
     400           0 :       child->GetTabId());
     401           0 :     ContentPermissionRequestChildMap()[req.get()] = child->GetTabId();
     402             : 
     403           0 :     req->Sendprompt();
     404           0 :     return NS_OK;
     405             :   }
     406             : 
     407             :   // for chrome process
     408             :   nsCOMPtr<nsIContentPermissionPrompt> prompt =
     409           0 :     do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
     410           0 :   if (prompt) {
     411           0 :     if (NS_FAILED(prompt->Prompt(aRequest))) {
     412           0 :       return NS_ERROR_FAILURE;
     413             :     }
     414             :   }
     415           0 :   return NS_OK;
     416             : }
     417             : 
     418             : /* static */ nsTArray<PContentPermissionRequestParent*>
     419           0 : nsContentPermissionUtils::GetContentPermissionRequestParentById(const TabId& aTabId)
     420             : {
     421           0 :   nsTArray<PContentPermissionRequestParent*> parentArray;
     422           0 :   for (auto& it : ContentPermissionRequestParentMap()) {
     423           0 :     if (it.second == aTabId) {
     424           0 :       parentArray.AppendElement(it.first);
     425             :     }
     426             :   }
     427             : 
     428           0 :   return Move(parentArray);
     429             : }
     430             : 
     431             : /* static */ void
     432           0 : nsContentPermissionUtils::NotifyRemoveContentPermissionRequestParent(
     433             :   PContentPermissionRequestParent* aParent)
     434             : {
     435           0 :   auto it = ContentPermissionRequestParentMap().find(aParent);
     436           0 :   MOZ_ASSERT(it != ContentPermissionRequestParentMap().end());
     437             : 
     438           0 :   ContentPermissionRequestParentMap().erase(it);
     439           0 : }
     440             : 
     441             : /* static */ nsTArray<PContentPermissionRequestChild*>
     442           0 : nsContentPermissionUtils::GetContentPermissionRequestChildById(const TabId& aTabId)
     443             : {
     444           0 :   nsTArray<PContentPermissionRequestChild*> childArray;
     445           0 :   for (auto& it : ContentPermissionRequestChildMap()) {
     446           0 :     if (it.second == aTabId) {
     447           0 :       childArray.AppendElement(it.first);
     448             :     }
     449             :   }
     450             : 
     451           0 :   return Move(childArray);
     452             : }
     453             : 
     454             : /* static */ void
     455           0 : nsContentPermissionUtils::NotifyRemoveContentPermissionRequestChild(
     456             :   PContentPermissionRequestChild* aChild)
     457             : {
     458           0 :   auto it = ContentPermissionRequestChildMap().find(aChild);
     459           0 :   MOZ_ASSERT(it != ContentPermissionRequestChildMap().end());
     460             : 
     461           0 :   ContentPermissionRequestChildMap().erase(it);
     462           0 : }
     463             : 
     464           0 : NS_IMPL_ISUPPORTS(nsContentPermissionRequester, nsIContentPermissionRequester)
     465             : 
     466           0 : nsContentPermissionRequester::nsContentPermissionRequester(nsPIDOMWindowInner* aWindow)
     467           0 :   : mWindow(do_GetWeakReference(aWindow))
     468           0 :   , mListener(new VisibilityChangeListener(aWindow))
     469             : {
     470           0 : }
     471             : 
     472           0 : nsContentPermissionRequester::~nsContentPermissionRequester()
     473             : {
     474           0 :   mListener->RemoveListener();
     475           0 :   mListener = nullptr;
     476           0 : }
     477             : 
     478             : NS_IMETHODIMP
     479           0 : nsContentPermissionRequester::GetVisibility(nsIContentPermissionRequestCallback* aCallback)
     480             : {
     481           0 :   NS_ENSURE_ARG_POINTER(aCallback);
     482             : 
     483           0 :   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(mWindow);
     484           0 :   if (!window) {
     485           0 :     return NS_ERROR_FAILURE;
     486             :   }
     487             : 
     488           0 :   nsCOMPtr<nsIDocShell> docshell = window->GetDocShell();
     489           0 :   if (!docshell) {
     490           0 :     return NS_ERROR_FAILURE;
     491             :   }
     492             : 
     493           0 :   bool isActive = false;
     494           0 :   docshell->GetIsActive(&isActive);
     495           0 :   aCallback->NotifyVisibility(isActive);
     496           0 :   return NS_OK;
     497             : }
     498             : 
     499             : NS_IMETHODIMP
     500           0 : nsContentPermissionRequester::SetOnVisibilityChange(nsIContentPermissionRequestCallback* aCallback)
     501             : {
     502           0 :   mListener->SetCallback(aCallback);
     503             : 
     504           0 :   if (!aCallback) {
     505           0 :     mListener->RemoveListener();
     506             :   }
     507             : 
     508           0 :   return NS_OK;
     509             : }
     510             : 
     511             : NS_IMETHODIMP
     512           0 : nsContentPermissionRequester::GetOnVisibilityChange(nsIContentPermissionRequestCallback** aCallback)
     513             : {
     514           0 :   NS_ENSURE_ARG_POINTER(aCallback);
     515             : 
     516           0 :   nsCOMPtr<nsIContentPermissionRequestCallback> callback = mListener->GetCallback();
     517           0 :   callback.forget(aCallback);
     518           0 :   return NS_OK;
     519             : }
     520             : 
     521             : } // namespace dom
     522             : } // namespace mozilla
     523             : 
     524           0 : NS_IMPL_ISUPPORTS(nsContentPermissionRequestProxy::nsContentPermissionRequesterProxy,
     525             :                   nsIContentPermissionRequester)
     526             : 
     527             : NS_IMETHODIMP
     528           0 : nsContentPermissionRequestProxy::nsContentPermissionRequesterProxy
     529             :   ::GetVisibility(nsIContentPermissionRequestCallback* aCallback)
     530             : {
     531           0 :   NS_ENSURE_ARG_POINTER(aCallback);
     532             : 
     533           0 :   mGetCallback = aCallback;
     534           0 :   mWaitGettingResult = true;
     535           0 :   Unused << mParent->SendGetVisibility();
     536           0 :   return NS_OK;
     537             : }
     538             : 
     539             : NS_IMETHODIMP
     540           0 : nsContentPermissionRequestProxy::nsContentPermissionRequesterProxy
     541             :   ::SetOnVisibilityChange(nsIContentPermissionRequestCallback* aCallback)
     542             : {
     543           0 :   mOnChangeCallback = aCallback;
     544           0 :   return NS_OK;
     545             : }
     546             : 
     547             : NS_IMETHODIMP
     548           0 : nsContentPermissionRequestProxy::nsContentPermissionRequesterProxy
     549             :   ::GetOnVisibilityChange(nsIContentPermissionRequestCallback** aCallback)
     550             : {
     551           0 :   NS_ENSURE_ARG_POINTER(aCallback);
     552             : 
     553           0 :   nsCOMPtr<nsIContentPermissionRequestCallback> callback = mOnChangeCallback;
     554           0 :   callback.forget(aCallback);
     555           0 :   return NS_OK;
     556             : }
     557             : 
     558             : void
     559           0 : nsContentPermissionRequestProxy::nsContentPermissionRequesterProxy
     560             :   ::NotifyVisibilityResult(const bool& aIsVisible)
     561             : {
     562           0 :   if (mWaitGettingResult) {
     563           0 :     MOZ_ASSERT(mGetCallback);
     564           0 :     mWaitGettingResult = false;
     565           0 :     mGetCallback->NotifyVisibility(aIsVisible);
     566           0 :     return;
     567             :   }
     568             : 
     569           0 :   if (mOnChangeCallback) {
     570           0 :     mOnChangeCallback->NotifyVisibility(aIsVisible);
     571             :   }
     572             : }
     573             : 
     574           0 : nsContentPermissionRequestProxy::nsContentPermissionRequestProxy()
     575             : {
     576           0 : }
     577             : 
     578           0 : nsContentPermissionRequestProxy::~nsContentPermissionRequestProxy()
     579             : {
     580           0 : }
     581             : 
     582             : nsresult
     583           0 : nsContentPermissionRequestProxy::Init(const nsTArray<PermissionRequest>& requests,
     584             :                                       ContentPermissionRequestParent* parent)
     585             : {
     586           0 :   NS_ASSERTION(parent, "null parent");
     587           0 :   mParent = parent;
     588           0 :   mPermissionRequests = requests;
     589           0 :   mRequester = new nsContentPermissionRequesterProxy(mParent);
     590             : 
     591           0 :   nsCOMPtr<nsIContentPermissionPrompt> prompt = do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
     592           0 :   if (!prompt) {
     593           0 :     return NS_ERROR_FAILURE;
     594             :   }
     595             : 
     596           0 :   prompt->Prompt(this);
     597           0 :   return NS_OK;
     598             : }
     599             : 
     600             : void
     601           0 : nsContentPermissionRequestProxy::OnParentDestroyed()
     602             : {
     603           0 :   mRequester = nullptr;
     604           0 :   mParent = nullptr;
     605           0 : }
     606             : 
     607           0 : NS_IMPL_ISUPPORTS(nsContentPermissionRequestProxy, nsIContentPermissionRequest)
     608             : 
     609             : NS_IMETHODIMP
     610           0 : nsContentPermissionRequestProxy::GetTypes(nsIArray** aTypes)
     611             : {
     612           0 :   nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
     613           0 :   if (mozilla::dom::nsContentPermissionUtils::ConvertPermissionRequestToArray(mPermissionRequests, types)) {
     614           0 :     types.forget(aTypes);
     615           0 :     return NS_OK;
     616             :   }
     617           0 :   return NS_ERROR_FAILURE;
     618             : }
     619             : 
     620             : NS_IMETHODIMP
     621           0 : nsContentPermissionRequestProxy::GetWindow(mozIDOMWindow * *aRequestingWindow)
     622             : {
     623           0 :   NS_ENSURE_ARG_POINTER(aRequestingWindow);
     624           0 :   *aRequestingWindow = nullptr; // ipc doesn't have a window
     625           0 :   return NS_OK;
     626             : }
     627             : 
     628             : NS_IMETHODIMP
     629           0 : nsContentPermissionRequestProxy::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
     630             : {
     631           0 :   NS_ENSURE_ARG_POINTER(aRequestingPrincipal);
     632           0 :   if (mParent == nullptr) {
     633           0 :     return NS_ERROR_FAILURE;
     634             :   }
     635             : 
     636           0 :   NS_ADDREF(*aRequestingPrincipal = mParent->mPrincipal);
     637           0 :   return NS_OK;
     638             : }
     639             : 
     640             : NS_IMETHODIMP
     641           0 : nsContentPermissionRequestProxy::GetElement(nsIDOMElement * *aRequestingElement)
     642             : {
     643           0 :   NS_ENSURE_ARG_POINTER(aRequestingElement);
     644           0 :   if (mParent == nullptr) {
     645           0 :     return NS_ERROR_FAILURE;
     646             :   }
     647             : 
     648           0 :   nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(mParent->mElement);
     649           0 :   elem.forget(aRequestingElement);
     650           0 :   return NS_OK;
     651             : }
     652             : 
     653             : NS_IMETHODIMP
     654           0 : nsContentPermissionRequestProxy::Cancel()
     655             : {
     656           0 :   if (mParent == nullptr) {
     657           0 :     return NS_ERROR_FAILURE;
     658             :   }
     659             : 
     660             :   // Don't send out the delete message when the managing protocol (PBrowser) is
     661             :   // being destroyed and PContentPermissionRequest will soon be.
     662           0 :   if (mParent->IsBeingDestroyed()) {
     663           0 :     return NS_ERROR_FAILURE;
     664             :   }
     665             : 
     666           0 :   nsTArray<PermissionChoice> emptyChoices;
     667             : 
     668           0 :   Unused << mParent->SendNotifyResult(false, emptyChoices);
     669           0 :   mParent = nullptr;
     670           0 :   return NS_OK;
     671             : }
     672             : 
     673             : NS_IMETHODIMP
     674           0 : nsContentPermissionRequestProxy::Allow(JS::HandleValue aChoices)
     675             : {
     676           0 :   if (mParent == nullptr) {
     677           0 :     return NS_ERROR_FAILURE;
     678             :   }
     679             : 
     680             :   // Don't send out the delete message when the managing protocol (PBrowser) is
     681             :   // being destroyed and PContentPermissionRequest will soon be.
     682           0 :   if (mParent->IsBeingDestroyed()) {
     683           0 :     return NS_ERROR_FAILURE;
     684             :   }
     685             : 
     686           0 :   nsTArray<PermissionChoice> choices;
     687           0 :   if (aChoices.isNullOrUndefined()) {
     688             :     // No choice is specified.
     689           0 :   } else if (aChoices.isObject()) {
     690             :     // Iterate through all permission types.
     691           0 :     for (uint32_t i = 0; i < mPermissionRequests.Length(); ++i) {
     692           0 :       nsCString type = mPermissionRequests[i].type();
     693             : 
     694           0 :       AutoJSAPI jsapi;
     695           0 :       jsapi.Init();
     696             : 
     697           0 :       JSContext* cx = jsapi.cx();
     698           0 :       JS::Rooted<JSObject*> obj(cx, &aChoices.toObject());
     699           0 :       JSAutoCompartment ac(cx, obj);
     700             : 
     701           0 :       JS::Rooted<JS::Value> val(cx);
     702             : 
     703           0 :       if (!JS_GetProperty(cx, obj, type.BeginReading(), &val) ||
     704           0 :           !val.isString()) {
     705             :         // no setting for the permission type, clear exception and skip it
     706           0 :         jsapi.ClearException();
     707             :       } else {
     708           0 :         nsAutoJSString choice;
     709           0 :         if (!choice.init(cx, val)) {
     710           0 :           jsapi.ClearException();
     711           0 :           return NS_ERROR_FAILURE;
     712             :         }
     713           0 :         choices.AppendElement(PermissionChoice(type, choice));
     714             :       }
     715             :     }
     716             :   } else {
     717           0 :     MOZ_ASSERT(false, "SelectedChoices should be undefined or an JS object");
     718             :     return NS_ERROR_FAILURE;
     719             :   }
     720             : 
     721           0 :   Unused << mParent->SendNotifyResult(true, choices);
     722           0 :   mParent = nullptr;
     723           0 :   return NS_OK;
     724             : }
     725             : 
     726             : void
     727           0 : nsContentPermissionRequestProxy::NotifyVisibility(const bool& aIsVisible)
     728             : {
     729           0 :   MOZ_ASSERT(mRequester);
     730             : 
     731           0 :   mRequester->NotifyVisibilityResult(aIsVisible);
     732           0 : }
     733             : 
     734             : NS_IMETHODIMP
     735           0 : nsContentPermissionRequestProxy::GetRequester(nsIContentPermissionRequester** aRequester)
     736             : {
     737           0 :   NS_ENSURE_ARG_POINTER(aRequester);
     738             : 
     739           0 :   RefPtr<nsContentPermissionRequesterProxy> requester = mRequester;
     740           0 :   requester.forget(aRequester);
     741           0 :   return NS_OK;
     742             : }
     743             : 
     744             : // RemotePermissionRequest
     745             : 
     746           0 : NS_IMPL_ISUPPORTS(RemotePermissionRequest, nsIContentPermissionRequestCallback);
     747             : 
     748           0 : RemotePermissionRequest::RemotePermissionRequest(
     749             :   nsIContentPermissionRequest* aRequest,
     750           0 :   nsPIDOMWindowInner* aWindow)
     751             :   : mRequest(aRequest)
     752             :   , mWindow(aWindow)
     753             :   , mIPCOpen(false)
     754           0 :   , mDestroyed(false)
     755             : {
     756           0 :   mListener = new VisibilityChangeListener(mWindow);
     757           0 :   mListener->SetCallback(this);
     758           0 : }
     759             : 
     760           0 : RemotePermissionRequest::~RemotePermissionRequest()
     761             : {
     762           0 :   MOZ_ASSERT(!mIPCOpen, "Protocol must not be open when RemotePermissionRequest is destroyed.");
     763           0 : }
     764             : 
     765             : void
     766           0 : RemotePermissionRequest::DoCancel()
     767             : {
     768           0 :   NS_ASSERTION(mRequest, "We need a request");
     769           0 :   mRequest->Cancel();
     770           0 : }
     771             : 
     772             : void
     773           0 : RemotePermissionRequest::DoAllow(JS::HandleValue aChoices)
     774             : {
     775           0 :   NS_ASSERTION(mRequest, "We need a request");
     776           0 :   mRequest->Allow(aChoices);
     777           0 : }
     778             : 
     779             : // PContentPermissionRequestChild
     780             : mozilla::ipc::IPCResult
     781           0 : RemotePermissionRequest::RecvNotifyResult(const bool& aAllow,
     782             :                                           InfallibleTArray<PermissionChoice>&& aChoices)
     783             : {
     784           0 :   Destroy();
     785             : 
     786           0 :   if (aAllow && mWindow->IsCurrentInnerWindow()) {
     787             :     // Use 'undefined' if no choice is provided.
     788           0 :     if (aChoices.IsEmpty()) {
     789           0 :       DoAllow(JS::UndefinedHandleValue);
     790           0 :       return IPC_OK();
     791             :     }
     792             : 
     793             :     // Convert choices to a JS val if any.
     794             :     // {"type1": "choice1", "type2": "choiceA"}
     795           0 :     AutoJSAPI jsapi;
     796           0 :     if (NS_WARN_IF(!jsapi.Init(mWindow))) {
     797           0 :       return IPC_OK(); // This is not an IPC error.
     798             :     }
     799             : 
     800           0 :     JSContext* cx = jsapi.cx();
     801           0 :     JS::Rooted<JSObject*> obj(cx);
     802           0 :     obj = JS_NewPlainObject(cx);
     803           0 :     for (uint32_t i = 0; i < aChoices.Length(); ++i) {
     804           0 :       const nsString& choice = aChoices[i].choice();
     805           0 :       const nsCString& type = aChoices[i].type();
     806           0 :       JS::Rooted<JSString*> jChoice(cx, JS_NewUCStringCopyN(cx, choice.get(), choice.Length()));
     807           0 :       JS::Rooted<JS::Value> vChoice(cx, StringValue(jChoice));
     808           0 :       if (!JS_SetProperty(cx, obj, type.get(), vChoice)) {
     809           0 :         return IPC_FAIL_NO_REASON(this);
     810             :       }
     811             :     }
     812           0 :     JS::RootedValue val(cx, JS::ObjectValue(*obj));
     813           0 :     DoAllow(val);
     814             :   } else {
     815           0 :     DoCancel();
     816             :   }
     817           0 :   return IPC_OK();
     818             : }
     819             : 
     820             : mozilla::ipc::IPCResult
     821           0 : RemotePermissionRequest::RecvGetVisibility()
     822             : {
     823           0 :   nsCOMPtr<nsIDocShell> docshell = mWindow->GetDocShell();
     824           0 :   if (!docshell) {
     825           0 :     return IPC_FAIL_NO_REASON(this);
     826             :   }
     827             : 
     828           0 :   bool isActive = false;
     829           0 :   docshell->GetIsActive(&isActive);
     830           0 :   Unused << SendNotifyVisibility(isActive);
     831           0 :   return IPC_OK();
     832             : }
     833             : 
     834             : void
     835           0 : RemotePermissionRequest::Destroy()
     836             : {
     837           0 :   if (!IPCOpen()) {
     838           0 :     return;
     839             :   }
     840           0 :   Unused << this->SendDestroy();
     841           0 :   mListener->RemoveListener();
     842           0 :   mListener = nullptr;
     843           0 :   mDestroyed = true;
     844             : }
     845             : 
     846             : NS_IMETHODIMP
     847           0 : RemotePermissionRequest::NotifyVisibility(bool isVisible)
     848             : {
     849           0 :   if (!IPCOpen()) {
     850           0 :     return NS_OK;
     851             :   }
     852             : 
     853           0 :   Unused << SendNotifyVisibility(isVisible);
     854           0 :   return NS_OK;
     855             : }

Generated by: LCOV version 1.13