1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "mozilla/dom/MIDIPermissionRequest.h"
8 #include "mozilla/dom/Document.h"
9 #include "mozilla/dom/MIDIAccessManager.h"
10 #include "mozilla/dom/MIDIOptionsBinding.h"
11 #include "nsIGlobalObject.h"
12 #include "mozilla/Preferences.h"
13 #include "nsContentUtils.h"
14
15 //-------------------------------------------------
16 // MIDI Permission Requests
17 //-------------------------------------------------
18
19 using namespace mozilla::dom;
20
NS_IMPL_CYCLE_COLLECTION_INHERITED(MIDIPermissionRequest,ContentPermissionRequestBase,mPromise)21 NS_IMPL_CYCLE_COLLECTION_INHERITED(MIDIPermissionRequest,
22 ContentPermissionRequestBase, mPromise)
23
24 NS_IMPL_QUERY_INTERFACE_CYCLE_COLLECTION_INHERITED(MIDIPermissionRequest,
25 ContentPermissionRequestBase,
26 nsIRunnable)
27
28 NS_IMPL_ADDREF_INHERITED(MIDIPermissionRequest, ContentPermissionRequestBase)
29 NS_IMPL_RELEASE_INHERITED(MIDIPermissionRequest, ContentPermissionRequestBase)
30
31 MIDIPermissionRequest::MIDIPermissionRequest(nsPIDOMWindowInner* aWindow,
32 Promise* aPromise,
33 const MIDIOptions& aOptions)
34 : ContentPermissionRequestBase(
35 aWindow->GetDoc()->NodePrincipal(), aWindow,
36 ""_ns, // We check prefs in a custom way here
37 "midi"_ns),
38 mPromise(aPromise),
39 mNeedsSysex(aOptions.mSysex) {
40 MOZ_ASSERT(aWindow);
41 MOZ_ASSERT(aPromise, "aPromise should not be null!");
42 MOZ_ASSERT(aWindow->GetDoc());
43 mPrincipal = aWindow->GetDoc()->NodePrincipal();
44 MOZ_ASSERT(mPrincipal);
45 }
46
47 NS_IMETHODIMP
GetTypes(nsIArray ** aTypes)48 MIDIPermissionRequest::GetTypes(nsIArray** aTypes) {
49 NS_ENSURE_ARG_POINTER(aTypes);
50 nsTArray<nsString> options;
51 if (mNeedsSysex) {
52 options.AppendElement(u"sysex"_ns);
53 }
54 return nsContentPermissionUtils::CreatePermissionArray(mType, options,
55 aTypes);
56 }
57
58 NS_IMETHODIMP
Cancel()59 MIDIPermissionRequest::Cancel() {
60 mPromise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
61 return NS_OK;
62 }
63
64 NS_IMETHODIMP
Allow(JS::HandleValue aChoices)65 MIDIPermissionRequest::Allow(JS::HandleValue aChoices) {
66 MOZ_ASSERT(aChoices.isUndefined());
67 MIDIAccessManager* mgr = MIDIAccessManager::Get();
68 mgr->CreateMIDIAccess(mWindow, mNeedsSysex, mPromise);
69 return NS_OK;
70 }
71
72 NS_IMETHODIMP
Run()73 MIDIPermissionRequest::Run() {
74 // If the testing flag is true, skip dialog
75 if (Preferences::GetBool("midi.prompt.testing", false)) {
76 bool allow =
77 Preferences::GetBool("media.navigator.permission.disabled", false);
78 if (allow) {
79 Allow(JS::UndefinedHandleValue);
80 } else {
81 Cancel();
82 }
83 return NS_OK;
84 }
85
86 // If we already have sysex perms, allow.
87 if (nsContentUtils::IsExactSitePermAllow(mPrincipal, "midi-sysex"_ns)) {
88 Allow(JS::UndefinedHandleValue);
89 return NS_OK;
90 }
91
92 // If we have no perms, or only have midi and are asking for sysex, pop dialog
93 if (NS_FAILED(nsContentPermissionUtils::AskPermission(this, mWindow))) {
94 Cancel();
95 return NS_ERROR_FAILURE;
96 }
97 return NS_OK;
98 }
99