Bug 1839170 - Refactor Snap pulling, Add Firefox Snap Core22 and GNOME 42 SDK symbols...
[gecko.git] / dom / permission / PermissionStatus.cpp
blob81e69d361cec2d2fb565ae4f2af5181c044670fd
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/. */
7 #include "mozilla/dom/PermissionStatus.h"
8 #include "mozilla/PermissionDelegateHandler.h"
10 #include "mozilla/AsyncEventDispatcher.h"
11 #include "mozilla/Permission.h"
12 #include "mozilla/Services.h"
13 #include "nsIPermissionManager.h"
14 #include "PermissionObserver.h"
15 #include "PermissionUtils.h"
17 namespace mozilla::dom {
19 /* static */
20 already_AddRefed<PermissionStatus> PermissionStatus::Create(
21 nsPIDOMWindowInner* aWindow, PermissionName aName, ErrorResult& aRv) {
22 RefPtr<PermissionStatus> status = new PermissionStatus(aWindow, aName);
23 aRv = status->Init();
24 if (NS_WARN_IF(aRv.Failed())) {
25 return nullptr;
28 return status.forget();
31 PermissionStatus::PermissionStatus(nsPIDOMWindowInner* aWindow,
32 PermissionName aName)
33 : DOMEventTargetHelper(aWindow),
34 mName(aName),
35 mState(PermissionState::Denied) {
36 KeepAliveIfHasListenersFor(nsGkAtoms::onchange);
39 nsresult PermissionStatus::Init() {
40 mObserver = PermissionObserver::GetInstance();
41 if (NS_WARN_IF(!mObserver)) {
42 return NS_ERROR_FAILURE;
45 mObserver->AddSink(this);
47 nsresult rv = UpdateState();
48 if (NS_WARN_IF(NS_FAILED(rv))) {
49 return rv;
52 return NS_OK;
55 PermissionStatus::~PermissionStatus() {
56 if (mObserver) {
57 mObserver->RemoveSink(this);
61 JSObject* PermissionStatus::WrapObject(JSContext* aCx,
62 JS::Handle<JSObject*> aGivenProto) {
63 return PermissionStatus_Binding::Wrap(aCx, this, aGivenProto);
66 nsLiteralCString PermissionStatus::GetPermissionType() {
67 return PermissionNameToType(mName);
70 nsresult PermissionStatus::UpdateState() {
71 nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
72 if (NS_WARN_IF(!window)) {
73 return NS_ERROR_FAILURE;
76 RefPtr<Document> document = window->GetExtantDoc();
77 if (NS_WARN_IF(!document)) {
78 return NS_ERROR_FAILURE;
81 uint32_t action = nsIPermissionManager::DENY_ACTION;
83 PermissionDelegateHandler* permissionHandler =
84 document->GetPermissionDelegateHandler();
85 if (NS_WARN_IF(!permissionHandler)) {
86 return NS_ERROR_FAILURE;
89 nsresult rv = permissionHandler->GetPermissionForPermissionsAPI(
90 GetPermissionType(), &action);
91 if (NS_WARN_IF(NS_FAILED(rv))) {
92 return rv;
95 mState = ActionToPermissionState(action);
96 return NS_OK;
99 already_AddRefed<nsIPrincipal> PermissionStatus::GetPrincipal() const {
100 nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
101 if (NS_WARN_IF(!window)) {
102 return nullptr;
105 Document* doc = window->GetExtantDoc();
106 if (NS_WARN_IF(!doc)) {
107 return nullptr;
110 nsCOMPtr<nsIPrincipal> principal =
111 Permission::ClonePrincipalForPermission(doc->NodePrincipal());
112 NS_ENSURE_TRUE(principal, nullptr);
114 return principal.forget();
117 void PermissionStatus::PermissionChanged() {
118 nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
119 if (NS_WARN_IF(!window) || !window->IsFullyActive()) {
120 return;
122 auto oldState = mState;
123 UpdateState();
124 if (mState != oldState) {
125 RefPtr<AsyncEventDispatcher> eventDispatcher =
126 new AsyncEventDispatcher(this, u"change"_ns, CanBubble::eNo);
127 eventDispatcher->PostDOMEvent();
131 void PermissionStatus::DisconnectFromOwner() {
132 IgnoreKeepAliveIfHasListenersFor(nsGkAtoms::onchange);
134 if (mObserver) {
135 mObserver->RemoveSink(this);
136 mObserver = nullptr;
139 DOMEventTargetHelper::DisconnectFromOwner();
142 } // namespace mozilla::dom