Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsIDOMClassInfo.h"
6 #include "nsIDOMEvent.h"
7 #include "nsIDOMEventListener.h"
8 #include "nsPIDOMWindow.h"
9 #include "nsIDocShell.h"
10 #include "nsIPermissionManager.h"
11 #include "nsIInterfaceRequestorUtils.h"
12 #include "AudioChannelManager.h"
13 #include "mozilla/dom/AudioChannelManagerBinding.h"
15 using namespace mozilla::hal;
17 namespace mozilla {
18 namespace dom {
19 namespace system {
21 NS_IMPL_QUERY_INTERFACE_INHERITED(AudioChannelManager, DOMEventTargetHelper,
22 nsIDOMEventListener)
23 NS_IMPL_ADDREF_INHERITED(AudioChannelManager, DOMEventTargetHelper)
24 NS_IMPL_RELEASE_INHERITED(AudioChannelManager, DOMEventTargetHelper)
26 AudioChannelManager::AudioChannelManager()
27 : mState(SWITCH_STATE_UNKNOWN)
28 , mVolumeChannel(-1)
29 {
30 RegisterSwitchObserver(SWITCH_HEADPHONES, this);
31 mState = GetCurrentSwitchState(SWITCH_HEADPHONES);
32 SetIsDOMBinding();
33 }
35 AudioChannelManager::~AudioChannelManager()
36 {
37 UnregisterSwitchObserver(SWITCH_HEADPHONES, this);
39 nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner());
40 NS_ENSURE_TRUE_VOID(target);
42 target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
43 this,
44 /* useCapture = */ true);
45 }
47 void
48 AudioChannelManager::Init(nsPIDOMWindow* aWindow)
49 {
50 BindToOwner(aWindow->IsOuterWindow() ?
51 aWindow->GetCurrentInnerWindow() : aWindow);
53 nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
54 NS_ENSURE_TRUE_VOID(target);
56 target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
57 this,
58 /* useCapture = */ true,
59 /* wantsUntrusted = */ false);
60 }
62 JSObject*
63 AudioChannelManager::WrapObject(JSContext* aCx)
64 {
65 return AudioChannelManagerBinding::Wrap(aCx, this);
66 }
68 void
69 AudioChannelManager::Notify(const SwitchEvent& aEvent)
70 {
71 mState = aEvent.status();
73 DispatchTrustedEvent(NS_LITERAL_STRING("headphoneschange"));
74 }
76 bool
77 AudioChannelManager::SetVolumeControlChannel(const nsAString& aChannel)
78 {
79 if (aChannel.EqualsASCII("publicnotification")) {
80 return false;
81 }
83 AudioChannel newChannel = AudioChannelService::GetAudioChannel(aChannel);
85 // Only normal channel doesn't need permission.
86 if (newChannel != AudioChannel::Normal) {
87 nsCOMPtr<nsIPermissionManager> permissionManager =
88 do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
89 if (!permissionManager) {
90 return false;
91 }
92 uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
93 permissionManager->TestPermissionFromWindow(GetOwner(),
94 nsCString(NS_LITERAL_CSTRING("audio-channel-") +
95 NS_ConvertUTF16toUTF8(aChannel)).get(), &perm);
96 if (perm != nsIPermissionManager::ALLOW_ACTION) {
97 return false;
98 }
99 }
101 if (mVolumeChannel == (int32_t)newChannel) {
102 return true;
103 }
105 mVolumeChannel = (int32_t)newChannel;
107 NotifyVolumeControlChannelChanged();
108 return true;
109 }
111 bool
112 AudioChannelManager::GetVolumeControlChannel(nsAString & aChannel)
113 {
114 if (mVolumeChannel >= 0) {
115 AudioChannelService::GetAudioChannelString(
116 static_cast<AudioChannel>(mVolumeChannel),
117 aChannel);
118 } else {
119 aChannel.AssignASCII("");
120 }
122 return true;
123 }
125 void
126 AudioChannelManager::NotifyVolumeControlChannelChanged()
127 {
128 nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner());
129 NS_ENSURE_TRUE_VOID(docshell);
131 bool isActive = false;
132 docshell->GetIsActive(&isActive);
134 AudioChannelService* service = AudioChannelService::GetAudioChannelService();
135 if (isActive) {
136 service->SetDefaultVolumeControlChannel(mVolumeChannel, isActive);
137 } else {
138 service->SetDefaultVolumeControlChannel(-1, isActive);
139 }
140 }
142 NS_IMETHODIMP
143 AudioChannelManager::HandleEvent(nsIDOMEvent* aEvent)
144 {
145 nsAutoString type;
146 aEvent->GetType(type);
148 if (type.EqualsLiteral("visibilitychange")) {
149 NotifyVolumeControlChannelChanged();
150 }
151 return NS_OK;
152 }
154 } // namespace system
155 } // namespace dom
156 } // namespace mozilla