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