gecko-dev/dom/html/AutoplayPermissionRequest.cpp
alwu 500a400737 Bug 1479218 - deny request when inner window is destroyed. r=cpearce
The AutoplayPermissionManager might be destroyed before the AutoplayPermissionRequest, so we can't
get the response from request before AutoplayPermissionManager is destroyed.

Therefore, we should manually reject the promise when the inner window is going to be destroyed.

Differential Revision: https://phabricator.services.mozilla.com/D5906

--HG--
extra : moz-landing-system : lando
2018-09-17 17:09:46 +00:00

148 lines
4.0 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/AutoplayPermissionRequest.h"
#include "mozilla/AutoplayPermissionManager.h"
#include "mozilla/Logging.h"
extern mozilla::LazyLogModule gAutoplayPermissionLog;
#define PLAY_REQUEST_LOG(msg, ...) \
MOZ_LOG(gAutoplayPermissionLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
namespace mozilla {
NS_IMPL_ISUPPORTS(AutoplayPermissionRequest, nsIContentPermissionRequest)
AutoplayPermissionRequest::AutoplayPermissionRequest(
AutoplayPermissionManager* aManager,
nsGlobalWindowInner* aWindow,
nsIPrincipal* aNodePrincipal,
nsIEventTarget* aMainThreadTarget)
: mManager(aManager)
, mWindow(do_GetWeakReference(aWindow))
, mNodePrincipal(aNodePrincipal)
, mMainThreadTarget(aMainThreadTarget)
, mRequester(new dom::nsContentPermissionRequester(aWindow))
{
MOZ_ASSERT(mNodePrincipal);
}
AutoplayPermissionRequest::~AutoplayPermissionRequest()
{
Cancel();
}
NS_IMETHODIMP
AutoplayPermissionRequest::GetPrincipal(nsIPrincipal** aRequestingPrincipal)
{
NS_ENSURE_ARG_POINTER(aRequestingPrincipal);
nsCOMPtr<nsIPrincipal> principal = mNodePrincipal;
principal.forget(aRequestingPrincipal);
return NS_OK;
}
NS_IMETHODIMP
AutoplayPermissionRequest::GetTypes(nsIArray** aTypes)
{
NS_ENSURE_ARG_POINTER(aTypes);
nsTArray<nsString> emptyOptions;
return dom::nsContentPermissionUtils::CreatePermissionArray(
NS_LITERAL_CSTRING("autoplay-media"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
}
NS_IMETHODIMP
AutoplayPermissionRequest::GetWindow(mozIDOMWindow** aRequestingWindow)
{
NS_ENSURE_ARG_POINTER(aRequestingWindow);
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(mWindow);
if (!window) {
return NS_ERROR_FAILURE;
}
window.forget(aRequestingWindow);
return NS_OK;
}
NS_IMETHODIMP
AutoplayPermissionRequest::GetElement(dom::Element** aRequestingElement)
{
NS_ENSURE_ARG_POINTER(aRequestingElement);
*aRequestingElement = nullptr;
return NS_OK;
}
NS_IMETHODIMP
AutoplayPermissionRequest::GetIsHandlingUserInput(bool* aIsHandlingUserInput)
{
NS_ENSURE_ARG_POINTER(aIsHandlingUserInput);
*aIsHandlingUserInput = false;
return NS_OK;
}
NS_IMETHODIMP
AutoplayPermissionRequest::Cancel()
{
if (mManager) {
mManager->DenyPlayRequestIfExists();
// Clear reference to manager, so we can't double report a result.
// This could happen in particular if we call Cancel() in the destructor.
mManager = nullptr;
}
return NS_OK;
}
NS_IMETHODIMP
AutoplayPermissionRequest::Allow(JS::HandleValue aChoices)
{
if (mManager) {
mManager->ApprovePlayRequestIfExists();
// Clear reference to manager, so we can't double report a result.
// This could happen in particular if we call Cancel() in the destructor.
mManager = nullptr;
}
return NS_OK;
}
NS_IMETHODIMP
AutoplayPermissionRequest::GetRequester(
nsIContentPermissionRequester** aRequester)
{
NS_ENSURE_ARG_POINTER(aRequester);
nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
requester.forget(aRequester);
return NS_OK;
}
already_AddRefed<AutoplayPermissionRequest>
AutoplayPermissionRequest::Create(nsGlobalWindowInner* aWindow,
AutoplayPermissionManager* aManager)
{
if (!aWindow || !aWindow->GetPrincipal() ||
!aWindow->EventTargetFor(TaskCategory::Other)) {
return nullptr;
}
RefPtr<AutoplayPermissionRequest> request =
new AutoplayPermissionRequest(aManager,
aWindow,
aWindow->GetPrincipal(),
aWindow->EventTargetFor(TaskCategory::Other));
PLAY_REQUEST_LOG("AutoplayPermissionRequest %p Create()", request.get());
return request.forget();
}
} // namespace mozilla