|
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/. */ |
|
4 |
|
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" |
|
14 |
|
15 using namespace mozilla::hal; |
|
16 |
|
17 namespace mozilla { |
|
18 namespace dom { |
|
19 namespace system { |
|
20 |
|
21 NS_IMPL_QUERY_INTERFACE_INHERITED(AudioChannelManager, DOMEventTargetHelper, |
|
22 nsIDOMEventListener) |
|
23 NS_IMPL_ADDREF_INHERITED(AudioChannelManager, DOMEventTargetHelper) |
|
24 NS_IMPL_RELEASE_INHERITED(AudioChannelManager, DOMEventTargetHelper) |
|
25 |
|
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 } |
|
34 |
|
35 AudioChannelManager::~AudioChannelManager() |
|
36 { |
|
37 UnregisterSwitchObserver(SWITCH_HEADPHONES, this); |
|
38 |
|
39 nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner()); |
|
40 NS_ENSURE_TRUE_VOID(target); |
|
41 |
|
42 target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), |
|
43 this, |
|
44 /* useCapture = */ true); |
|
45 } |
|
46 |
|
47 void |
|
48 AudioChannelManager::Init(nsPIDOMWindow* aWindow) |
|
49 { |
|
50 BindToOwner(aWindow->IsOuterWindow() ? |
|
51 aWindow->GetCurrentInnerWindow() : aWindow); |
|
52 |
|
53 nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner()); |
|
54 NS_ENSURE_TRUE_VOID(target); |
|
55 |
|
56 target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"), |
|
57 this, |
|
58 /* useCapture = */ true, |
|
59 /* wantsUntrusted = */ false); |
|
60 } |
|
61 |
|
62 JSObject* |
|
63 AudioChannelManager::WrapObject(JSContext* aCx) |
|
64 { |
|
65 return AudioChannelManagerBinding::Wrap(aCx, this); |
|
66 } |
|
67 |
|
68 void |
|
69 AudioChannelManager::Notify(const SwitchEvent& aEvent) |
|
70 { |
|
71 mState = aEvent.status(); |
|
72 |
|
73 DispatchTrustedEvent(NS_LITERAL_STRING("headphoneschange")); |
|
74 } |
|
75 |
|
76 bool |
|
77 AudioChannelManager::SetVolumeControlChannel(const nsAString& aChannel) |
|
78 { |
|
79 if (aChannel.EqualsASCII("publicnotification")) { |
|
80 return false; |
|
81 } |
|
82 |
|
83 AudioChannel newChannel = AudioChannelService::GetAudioChannel(aChannel); |
|
84 |
|
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 } |
|
100 |
|
101 if (mVolumeChannel == (int32_t)newChannel) { |
|
102 return true; |
|
103 } |
|
104 |
|
105 mVolumeChannel = (int32_t)newChannel; |
|
106 |
|
107 NotifyVolumeControlChannelChanged(); |
|
108 return true; |
|
109 } |
|
110 |
|
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 } |
|
121 |
|
122 return true; |
|
123 } |
|
124 |
|
125 void |
|
126 AudioChannelManager::NotifyVolumeControlChannelChanged() |
|
127 { |
|
128 nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner()); |
|
129 NS_ENSURE_TRUE_VOID(docshell); |
|
130 |
|
131 bool isActive = false; |
|
132 docshell->GetIsActive(&isActive); |
|
133 |
|
134 AudioChannelService* service = AudioChannelService::GetAudioChannelService(); |
|
135 if (isActive) { |
|
136 service->SetDefaultVolumeControlChannel(mVolumeChannel, isActive); |
|
137 } else { |
|
138 service->SetDefaultVolumeControlChannel(-1, isActive); |
|
139 } |
|
140 } |
|
141 |
|
142 NS_IMETHODIMP |
|
143 AudioChannelManager::HandleEvent(nsIDOMEvent* aEvent) |
|
144 { |
|
145 nsAutoString type; |
|
146 aEvent->GetType(type); |
|
147 |
|
148 if (type.EqualsLiteral("visibilitychange")) { |
|
149 NotifyVolumeControlChannelChanged(); |
|
150 } |
|
151 return NS_OK; |
|
152 } |
|
153 |
|
154 } // namespace system |
|
155 } // namespace dom |
|
156 } // namespace mozilla |