123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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/dom/Permissions.h"
- #include "mozilla/dom/ContentChild.h"
- #include "mozilla/dom/PermissionsBinding.h"
- #include "mozilla/dom/Promise.h"
- #include "mozilla/Services.h"
- #include "nsIPermissionManager.h"
- #include "PermissionStatus.h"
- #include "PermissionUtils.h"
- namespace mozilla {
- namespace dom {
- NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Permissions)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
- NS_INTERFACE_MAP_END
- NS_IMPL_CYCLE_COLLECTING_ADDREF(Permissions)
- NS_IMPL_CYCLE_COLLECTING_RELEASE(Permissions)
- NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Permissions, mWindow)
- Permissions::Permissions(nsPIDOMWindowInner* aWindow)
- : mWindow(aWindow)
- {
- }
- Permissions::~Permissions()
- {
- }
- JSObject*
- Permissions::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
- {
- return PermissionsBinding::Wrap(aCx, this, aGivenProto);
- }
- namespace {
- already_AddRefed<PermissionStatus>
- CreatePermissionStatus(JSContext* aCx,
- JS::Handle<JSObject*> aPermission,
- nsPIDOMWindowInner* aWindow,
- ErrorResult& aRv)
- {
- PermissionDescriptor permission;
- JS::Rooted<JS::Value> value(aCx, JS::ObjectOrNullValue(aPermission));
- if (NS_WARN_IF(!permission.Init(aCx, value))) {
- aRv.NoteJSContextException(aCx);
- return nullptr;
- }
- switch (permission.mName) {
- case PermissionName::Geolocation:
- case PermissionName::Notifications:
- case PermissionName::Push:
- return PermissionStatus::Create(aWindow, permission.mName, aRv);
- default:
- MOZ_ASSERT_UNREACHABLE("Unhandled type");
- aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
- return nullptr;
- }
- }
- } // namespace
- already_AddRefed<Promise>
- Permissions::Query(JSContext* aCx,
- JS::Handle<JSObject*> aPermission,
- ErrorResult& aRv)
- {
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
- if (!global) {
- aRv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
- RefPtr<PermissionStatus> status =
- CreatePermissionStatus(aCx, aPermission, mWindow, aRv);
- if (NS_WARN_IF(aRv.Failed())) {
- MOZ_ASSERT(!status);
- return nullptr;
- }
- MOZ_ASSERT(status);
- RefPtr<Promise> promise = Promise::Create(global, aRv);
- if (NS_WARN_IF(aRv.Failed())) {
- return nullptr;
- }
- promise->MaybeResolve(status);
- return promise.forget();
- }
- /* static */ nsresult
- Permissions::RemovePermission(nsIPrincipal* aPrincipal, const char* aPermissionType)
- {
- MOZ_ASSERT(XRE_IsParentProcess());
- nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
- if (NS_WARN_IF(!permMgr)) {
- return NS_ERROR_FAILURE;
- }
- return permMgr->RemoveFromPrincipal(aPrincipal, aPermissionType);
- }
- already_AddRefed<Promise>
- Permissions::Revoke(JSContext* aCx,
- JS::Handle<JSObject*> aPermission,
- ErrorResult& aRv)
- {
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
- if (!global) {
- aRv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
- PermissionDescriptor permission;
- JS::Rooted<JS::Value> value(aCx, JS::ObjectOrNullValue(aPermission));
- if (NS_WARN_IF(!permission.Init(aCx, value))) {
- aRv.NoteJSContextException(aCx);
- return nullptr;
- }
- RefPtr<Promise> promise = Promise::Create(global, aRv);
- if (NS_WARN_IF(aRv.Failed())) {
- return nullptr;
- }
- nsCOMPtr<nsIDocument> document = mWindow->GetExtantDoc();
- if (!document) {
- promise->MaybeReject(NS_ERROR_UNEXPECTED);
- return promise.forget();
- }
- nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
- if (NS_WARN_IF(!permMgr)) {
- promise->MaybeReject(NS_ERROR_FAILURE);
- return promise.forget();
- }
- const char* permissionType = PermissionNameToType(permission.mName);
- nsresult rv;
- if (XRE_IsParentProcess()) {
- rv = RemovePermission(document->NodePrincipal(), permissionType);
- } else {
- // Permissions can't be removed from the content process. Send a message
- // to the parent; `ContentParent::RecvRemovePermission` will call
- // `RemovePermission`.
- ContentChild::GetSingleton()->SendRemovePermission(
- IPC::Principal(document->NodePrincipal()), nsDependentCString(permissionType), &rv);
- }
- if (NS_WARN_IF(NS_FAILED(rv))) {
- promise->MaybeReject(rv);
- return promise.forget();
- }
- RefPtr<PermissionStatus> status =
- CreatePermissionStatus(aCx, aPermission, mWindow, aRv);
- if (NS_WARN_IF(aRv.Failed())) {
- MOZ_ASSERT(!status);
- return nullptr;
- }
- MOZ_ASSERT(status);
- promise->MaybeResolve(status);
- return promise.forget();
- }
- } // namespace dom
- } // namespace mozilla
|