michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsIDOMClassInfo.h" michael@0: #include "nsIDOMEvent.h" michael@0: #include "nsIDOMEventListener.h" michael@0: #include "nsPIDOMWindow.h" michael@0: #include "nsIDocShell.h" michael@0: #include "nsIPermissionManager.h" michael@0: #include "nsIInterfaceRequestorUtils.h" michael@0: #include "AudioChannelManager.h" michael@0: #include "mozilla/dom/AudioChannelManagerBinding.h" michael@0: michael@0: using namespace mozilla::hal; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: namespace system { michael@0: michael@0: NS_IMPL_QUERY_INTERFACE_INHERITED(AudioChannelManager, DOMEventTargetHelper, michael@0: nsIDOMEventListener) michael@0: NS_IMPL_ADDREF_INHERITED(AudioChannelManager, DOMEventTargetHelper) michael@0: NS_IMPL_RELEASE_INHERITED(AudioChannelManager, DOMEventTargetHelper) michael@0: michael@0: AudioChannelManager::AudioChannelManager() michael@0: : mState(SWITCH_STATE_UNKNOWN) michael@0: , mVolumeChannel(-1) michael@0: { michael@0: RegisterSwitchObserver(SWITCH_HEADPHONES, this); michael@0: mState = GetCurrentSwitchState(SWITCH_HEADPHONES); michael@0: SetIsDOMBinding(); michael@0: } michael@0: michael@0: AudioChannelManager::~AudioChannelManager() michael@0: { michael@0: UnregisterSwitchObserver(SWITCH_HEADPHONES, this); michael@0: michael@0: nsCOMPtr target = do_QueryInterface(GetOwner()); michael@0: NS_ENSURE_TRUE_VOID(target); michael@0: michael@0: target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), michael@0: this, michael@0: /* useCapture = */ true); michael@0: } michael@0: michael@0: void michael@0: AudioChannelManager::Init(nsPIDOMWindow* aWindow) michael@0: { michael@0: BindToOwner(aWindow->IsOuterWindow() ? michael@0: aWindow->GetCurrentInnerWindow() : aWindow); michael@0: michael@0: nsCOMPtr target = do_QueryInterface(GetOwner()); michael@0: NS_ENSURE_TRUE_VOID(target); michael@0: michael@0: target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"), michael@0: this, michael@0: /* useCapture = */ true, michael@0: /* wantsUntrusted = */ false); michael@0: } michael@0: michael@0: JSObject* michael@0: AudioChannelManager::WrapObject(JSContext* aCx) michael@0: { michael@0: return AudioChannelManagerBinding::Wrap(aCx, this); michael@0: } michael@0: michael@0: void michael@0: AudioChannelManager::Notify(const SwitchEvent& aEvent) michael@0: { michael@0: mState = aEvent.status(); michael@0: michael@0: DispatchTrustedEvent(NS_LITERAL_STRING("headphoneschange")); michael@0: } michael@0: michael@0: bool michael@0: AudioChannelManager::SetVolumeControlChannel(const nsAString& aChannel) michael@0: { michael@0: if (aChannel.EqualsASCII("publicnotification")) { michael@0: return false; michael@0: } michael@0: michael@0: AudioChannel newChannel = AudioChannelService::GetAudioChannel(aChannel); michael@0: michael@0: // Only normal channel doesn't need permission. michael@0: if (newChannel != AudioChannel::Normal) { michael@0: nsCOMPtr permissionManager = michael@0: do_GetService(NS_PERMISSIONMANAGER_CONTRACTID); michael@0: if (!permissionManager) { michael@0: return false; michael@0: } michael@0: uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION; michael@0: permissionManager->TestPermissionFromWindow(GetOwner(), michael@0: nsCString(NS_LITERAL_CSTRING("audio-channel-") + michael@0: NS_ConvertUTF16toUTF8(aChannel)).get(), &perm); michael@0: if (perm != nsIPermissionManager::ALLOW_ACTION) { michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: if (mVolumeChannel == (int32_t)newChannel) { michael@0: return true; michael@0: } michael@0: michael@0: mVolumeChannel = (int32_t)newChannel; michael@0: michael@0: NotifyVolumeControlChannelChanged(); michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: AudioChannelManager::GetVolumeControlChannel(nsAString & aChannel) michael@0: { michael@0: if (mVolumeChannel >= 0) { michael@0: AudioChannelService::GetAudioChannelString( michael@0: static_cast(mVolumeChannel), michael@0: aChannel); michael@0: } else { michael@0: aChannel.AssignASCII(""); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: AudioChannelManager::NotifyVolumeControlChannelChanged() michael@0: { michael@0: nsCOMPtr docshell = do_GetInterface(GetOwner()); michael@0: NS_ENSURE_TRUE_VOID(docshell); michael@0: michael@0: bool isActive = false; michael@0: docshell->GetIsActive(&isActive); michael@0: michael@0: AudioChannelService* service = AudioChannelService::GetAudioChannelService(); michael@0: if (isActive) { michael@0: service->SetDefaultVolumeControlChannel(mVolumeChannel, isActive); michael@0: } else { michael@0: service->SetDefaultVolumeControlChannel(-1, isActive); michael@0: } michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: AudioChannelManager::HandleEvent(nsIDOMEvent* aEvent) michael@0: { michael@0: nsAutoString type; michael@0: aEvent->GetType(type); michael@0: michael@0: if (type.EqualsLiteral("visibilitychange")) { michael@0: NotifyVolumeControlChannelChanged(); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: } // namespace system michael@0: } // namespace dom michael@0: } // namespace mozilla