[Mac] don't enable low power audio mode on external output devices
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Jul 2014 18:17:34 +0000 (18:17 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Jul 2014 18:17:34 +0000 (18:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134877

Reviewed by Sam Weinig.

Source/WebCore:
No new tests, this deals with changes to the audio hardware at runtime.

* WebCore.xcodeproj/project.pbxproj: Remove AudioSessionListener.h.
* WebCore.vcxproj/WebCore.vcxproj: Ditto.

* platform/audio/AudioHardwareListener.cpp:
(WebCore::AudioHardwareListener::AudioHardwareListener): Initialize m_outputDeviceSupportsLowPowerMode
    to true on iOS.
* platform/audio/AudioHardwareListener.h:
(WebCore::AudioHardwareListener::outputDeviceSupportsLowPowerMode): New accessor.
(WebCore::AudioHardwareListener::setHardwareActivity): New setter for derived classes.
(WebCore::AudioHardwareListener::setOutputDeviceSupportsLowPowerMode): Ditto.

Remove AudioSessionListener interface, it wasn't being used.
* platform/audio/AudioSession.cpp:
(WebCore::AudioSession::addListener): Deleted.
(WebCore::AudioSession::removeListener): Deleted.
(WebCore::AudioSession::beganAudioInterruption): Deleted.
(WebCore::AudioSession::endedAudioInterruption): Deleted.
* platform/audio/AudioSession.h:
* platform/audio/AudioSessionListener.h: Removed.

* platform/audio/MediaSessionManager.cpp:
(WebCore::MediaSessionManager::addSession): Allocate the AudioHardwareListener if necessary.
(WebCore::MediaSessionManager::removeSession): Free the AudioHardwareListener if necessary.
(WebCore::MediaSessionManager::audioOutputDeviceChanged): AudioHardwareListener client interface
    called when the output device changes, call updateSessionState to make sure we are using
    the correct buffer size.
* platform/audio/MediaSessionManager.h:

* platform/audio/ios/AudioDestinationIOS.h:
* platform/audio/ios/AudioSessionIOS.mm:
(WebCore::AudioSessionPrivate::AudioSessionPrivate): Drive-by cleanup, remove ObjC helper object
    that was used to listen for OS notifications, it is no longer used.
(SOFT_LINK_POINTER): Deleted.
(-[WebAudioSessionHelper initWithCallback:]): Deleted.
(-[WebAudioSessionHelper dealloc]): Deleted.
(-[WebAudioSessionHelper interruption:]): Deleted.

* platform/audio/mac/AudioHardwareListenerMac.cpp:
(WebCore::currentDeviceSupportsLowPowerBufferSize): New, return true only if using build-in
    transport device.
(WebCore::processIsRunningPropertyDescriptor): Return reference to static AudioObjectPropertyAddress
    for kAudioHardwarePropertyProcessIsRunning instead of declaring one in every method
    that needs one.
(WebCore::outputDevicePropertyDescriptor): Return reference to static AudioObjectPropertyAddress
    for kAudioHardwarePropertyDefaultOutputDevice.
(WebCore::AudioHardwareListenerMac::AudioHardwareListenerMac): Restructure and add audio object
    listener for default output device.
(WebCore::AudioHardwareListenerMac::~AudioHardwareListenerMac): *Remove* listener audio object
    property listener instead of *Adding* a new one. Remove new listener.
(WebCore::AudioHardwareListenerMac::propertyChanged): Enumerate the properties that changed,
    call appropriate method.
(WebCore::AudioHardwareListenerMac::processIsRunningChanged): Renamed from setHardwareActive,
    cleanup.
(WebCore::AudioHardwareListenerMac::outputDeviceChanged): New, call client.audioHardwareOutputDeviceChanged.
(WebCore::AudioHardwareListenerMac::setHardwareActive): Deleted, renamed processIsRunningChanged.
* platform/audio/mac/AudioHardwareListenerMac.h:

* platform/audio/mac/MediaSessionManagerMac.cpp:
(MediaSessionManager::updateSessionState): Only set the output buffer size to 4K when hardware
    supports it.

Source/WebKit2:
* PluginProcess/PluginProcess.h: Add an empty implementation of
    AudioHardwareListener::audioOutputDeviceChanged.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@171069 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/audio/AudioHardwareListener.cpp
Source/WebCore/platform/audio/AudioHardwareListener.h
Source/WebCore/platform/audio/AudioSession.cpp
Source/WebCore/platform/audio/AudioSession.h
Source/WebCore/platform/audio/AudioSessionListener.h [deleted file]
Source/WebCore/platform/audio/MediaSessionManager.cpp
Source/WebCore/platform/audio/MediaSessionManager.h
Source/WebCore/platform/audio/ios/AudioDestinationIOS.h
Source/WebCore/platform/audio/ios/AudioSessionIOS.mm
Source/WebCore/platform/audio/mac/AudioHardwareListenerMac.cpp
Source/WebCore/platform/audio/mac/AudioHardwareListenerMac.h
Source/WebCore/platform/audio/mac/MediaSessionManagerMac.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/PluginProcess/PluginProcess.h

index 71a60067432a52c882ff25d258f4ee1a7d51882b..9b049132c78d2a49bc579277e9b182115aff53b6 100644 (file)
@@ -1,3 +1,73 @@
+2014-07-14  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] don't enable low power audio mode on external output devices
+        https://bugs.webkit.org/show_bug.cgi?id=134877
+
+        Reviewed by Sam Weinig.
+
+        No new tests, this deals with changes to the audio hardware at runtime.
+
+        * WebCore.xcodeproj/project.pbxproj: Remove AudioSessionListener.h.
+        * WebCore.vcxproj/WebCore.vcxproj: Ditto.
+
+        * platform/audio/AudioHardwareListener.cpp:
+        (WebCore::AudioHardwareListener::AudioHardwareListener): Initialize m_outputDeviceSupportsLowPowerMode
+            to true on iOS.
+        * platform/audio/AudioHardwareListener.h:
+        (WebCore::AudioHardwareListener::outputDeviceSupportsLowPowerMode): New accessor.
+        (WebCore::AudioHardwareListener::setHardwareActivity): New setter for derived classes.
+        (WebCore::AudioHardwareListener::setOutputDeviceSupportsLowPowerMode): Ditto.
+
+        Remove AudioSessionListener interface, it wasn't being used.
+        * platform/audio/AudioSession.cpp:
+        (WebCore::AudioSession::addListener): Deleted.
+        (WebCore::AudioSession::removeListener): Deleted.
+        (WebCore::AudioSession::beganAudioInterruption): Deleted.
+        (WebCore::AudioSession::endedAudioInterruption): Deleted.
+        * platform/audio/AudioSession.h:
+        * platform/audio/AudioSessionListener.h: Removed.
+
+        * platform/audio/MediaSessionManager.cpp:
+        (WebCore::MediaSessionManager::addSession): Allocate the AudioHardwareListener if necessary.
+        (WebCore::MediaSessionManager::removeSession): Free the AudioHardwareListener if necessary.
+        (WebCore::MediaSessionManager::audioOutputDeviceChanged): AudioHardwareListener client interface
+            called when the output device changes, call updateSessionState to make sure we are using
+            the correct buffer size.
+        * platform/audio/MediaSessionManager.h:
+
+        * platform/audio/ios/AudioDestinationIOS.h:
+        * platform/audio/ios/AudioSessionIOS.mm:
+        (WebCore::AudioSessionPrivate::AudioSessionPrivate): Drive-by cleanup, remove ObjC helper object
+            that was used to listen for OS notifications, it is no longer used.
+        (SOFT_LINK_POINTER): Deleted.
+        (-[WebAudioSessionHelper initWithCallback:]): Deleted.
+        (-[WebAudioSessionHelper dealloc]): Deleted.
+        (-[WebAudioSessionHelper interruption:]): Deleted.
+
+        * platform/audio/mac/AudioHardwareListenerMac.cpp:
+        (WebCore::currentDeviceSupportsLowPowerBufferSize): New, return true only if using build-in 
+            transport device.
+        (WebCore::processIsRunningPropertyDescriptor): Return reference to static AudioObjectPropertyAddress
+            for kAudioHardwarePropertyProcessIsRunning instead of declaring one in every method
+            that needs one.
+        (WebCore::outputDevicePropertyDescriptor): Return reference to static AudioObjectPropertyAddress
+            for kAudioHardwarePropertyDefaultOutputDevice.
+        (WebCore::AudioHardwareListenerMac::AudioHardwareListenerMac): Restructure and add audio object
+            listener for default output device.
+        (WebCore::AudioHardwareListenerMac::~AudioHardwareListenerMac): *Remove* listener audio object
+            property listener instead of *Adding* a new one. Remove new listener.
+        (WebCore::AudioHardwareListenerMac::propertyChanged): Enumerate the properties that changed,
+            call appropriate method.
+        (WebCore::AudioHardwareListenerMac::processIsRunningChanged): Renamed from setHardwareActive, 
+            cleanup.
+        (WebCore::AudioHardwareListenerMac::outputDeviceChanged): New, call client.audioHardwareOutputDeviceChanged.
+        (WebCore::AudioHardwareListenerMac::setHardwareActive): Deleted, renamed processIsRunningChanged.
+        * platform/audio/mac/AudioHardwareListenerMac.h:
+
+        * platform/audio/mac/MediaSessionManagerMac.cpp:
+        (MediaSessionManager::updateSessionState): Only set the output buffer size to 4K when hardware
+            supports it.
+
 2014-07-13  Benjamin Poulain  <benjamin@webkit.org>
 
         Remove SelectorCheckerFastPath from the style resolution algorithm
 2014-07-13  Benjamin Poulain  <benjamin@webkit.org>
 
         Remove SelectorCheckerFastPath from the style resolution algorithm
index 8af6b5d01f34fb888e3a3b71cf85116c310da295..97892bd39488d5c6933c485582e64e3f1911c22b 100644 (file)
     <ClInclude Include="..\platform\FileSystem.h" />
     <ClInclude Include="..\platform\FloatConversion.h" />
     <ClInclude Include="..\platform\audio\AudioSession.h" />
     <ClInclude Include="..\platform\FileSystem.h" />
     <ClInclude Include="..\platform\FloatConversion.h" />
     <ClInclude Include="..\platform\audio\AudioSession.h" />
-    <ClInclude Include="..\platform\audio\AudioSessionListener.h" />
     <ClInclude Include="..\platform\audio\MediaSession.h" />
     <ClInclude Include="..\platform\audio\MediaSessionManager.h" />
     <ClInclude Include="..\platform\graphics\ANGLEWebKitBridge.h" />
     <ClInclude Include="..\platform\audio\MediaSession.h" />
     <ClInclude Include="..\platform\audio\MediaSessionManager.h" />
     <ClInclude Include="..\platform\graphics\ANGLEWebKitBridge.h" />
index ec7ce4cc00d71ef5ed80977fe535d1800ce89759..db2554e486de7155610da6b7cc2d5f8042ab4280 100644 (file)
                CDA07FBF18E0A22B004699FA /* SystemSleepListenerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemSleepListenerMac.mm; sourceTree = "<group>"; };
                CDA07FC018E0A22B004699FA /* SystemSleepListenerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemSleepListenerMac.h; sourceTree = "<group>"; };
                CDA79821170A22DC00D45C55 /* AudioSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioSession.h; sourceTree = "<group>"; };
                CDA07FBF18E0A22B004699FA /* SystemSleepListenerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemSleepListenerMac.mm; sourceTree = "<group>"; };
                CDA07FC018E0A22B004699FA /* SystemSleepListenerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemSleepListenerMac.h; sourceTree = "<group>"; };
                CDA79821170A22DC00D45C55 /* AudioSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioSession.h; sourceTree = "<group>"; };
-               CDA79822170A24F400D45C55 /* AudioSessionListener.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioSessionListener.h; sourceTree = "<group>"; };
                CDA79823170A258300D45C55 /* AudioSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioSession.cpp; sourceTree = "<group>"; };
                CDA79825170A279000D45C55 /* AudioSessionIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AudioSessionIOS.mm; path = ios/AudioSessionIOS.mm; sourceTree = "<group>"; };
                CDA98D9B160128A500FEA3B1 /* JSMediaKeyError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaKeyError.cpp; sourceTree = "<group>"; };
                CDA79823170A258300D45C55 /* AudioSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioSession.cpp; sourceTree = "<group>"; };
                CDA79825170A279000D45C55 /* AudioSessionIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AudioSessionIOS.mm; path = ios/AudioSessionIOS.mm; sourceTree = "<group>"; };
                CDA98D9B160128A500FEA3B1 /* JSMediaKeyError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaKeyError.cpp; sourceTree = "<group>"; };
                                FD31605212B026F700C1A359 /* AudioResamplerKernel.h */,
                                CDA79823170A258300D45C55 /* AudioSession.cpp */,
                                CDA79821170A22DC00D45C55 /* AudioSession.h */,
                                FD31605212B026F700C1A359 /* AudioResamplerKernel.h */,
                                CDA79823170A258300D45C55 /* AudioSession.cpp */,
                                CDA79821170A22DC00D45C55 /* AudioSession.h */,
-                               CDA79822170A24F400D45C55 /* AudioSessionListener.h */,
                                FD31605312B026F700C1A359 /* AudioSourceProvider.h */,
                                FD62F52D145898D80094B0ED /* AudioSourceProviderClient.h */,
                                FD31605412B026F700C1A359 /* AudioUtilities.cpp */,
                                FD31605312B026F700C1A359 /* AudioSourceProvider.h */,
                                FD62F52D145898D80094B0ED /* AudioSourceProviderClient.h */,
                                FD31605412B026F700C1A359 /* AudioUtilities.cpp */,
index 61b3a926378a9f576ca5f805c1418cf9fb76821f..5929228af12a05250f661ccdb135b856f26b2bb1 100644 (file)
@@ -38,8 +38,11 @@ PassRefPtr<AudioHardwareListener> AudioHardwareListener::create(Client& client)
 AudioHardwareListener::AudioHardwareListener(Client& client)
     : m_client(client)
     , m_activity(AudioHardwareActivityType::Unknown)
 AudioHardwareListener::AudioHardwareListener(Client& client)
     : m_client(client)
     , m_activity(AudioHardwareActivityType::Unknown)
+    , m_outputDeviceSupportsLowPowerMode(false)
 {
 {
-    
+#if PLATFORM(IOS)
+    m_outputDeviceSupportsLowPowerMode = true;
+#endif
 }
 
 }
 }
 
 }
index 9ddd43240c41b1eeff6570da68ba0e57e4f4e1c3..710d878687aa24e47ab18a4771eb5fb2236ff290 100644 (file)
@@ -44,18 +44,24 @@ public:
         virtual ~Client() { }
         virtual void audioHardwareDidBecomeActive() = 0;
         virtual void audioHardwareDidBecomeInactive() = 0;
         virtual ~Client() { }
         virtual void audioHardwareDidBecomeActive() = 0;
         virtual void audioHardwareDidBecomeInactive() = 0;
+        virtual void audioOutputDeviceChanged() = 0;
     };
 
     static PassRefPtr<AudioHardwareListener> create(Client&);
     virtual ~AudioHardwareListener() { }
     
     AudioHardwareActivityType hardwareActivity() const { return m_activity; }
     };
 
     static PassRefPtr<AudioHardwareListener> create(Client&);
     virtual ~AudioHardwareListener() { }
     
     AudioHardwareActivityType hardwareActivity() const { return m_activity; }
+    bool outputDeviceSupportsLowPowerMode() const { return m_outputDeviceSupportsLowPowerMode; }
 
 protected:
     AudioHardwareListener(Client&);
 
 
 protected:
     AudioHardwareListener(Client&);
 
+    void setHardwareActivity(AudioHardwareActivityType activity) { m_activity = activity; }
+    void setOutputDeviceSupportsLowPowerMode(bool support) { m_outputDeviceSupportsLowPowerMode = support; }
+
     Client& m_client;
     AudioHardwareActivityType m_activity;
     Client& m_client;
     AudioHardwareActivityType m_activity;
+    bool m_outputDeviceSupportsLowPowerMode;
 };
 
 }
 };
 
 }
index e2021484c833b2bc9b41f6468e453fb8f87377dd..f4db4fef045ec97843f009155f4aad10034414d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,6 @@
 
 #if USE(AUDIO_SESSION)
 
 
 #if USE(AUDIO_SESSION)
 
-#include "AudioSessionListener.h"
 #include "NotImplemented.h"
 
 namespace WebCore {
 #include "NotImplemented.h"
 
 namespace WebCore {
@@ -39,28 +38,6 @@ AudioSession& AudioSession::sharedSession()
     return session;
 }
 
     return session;
 }
 
-void AudioSession::addListener(AudioSessionListener* listener)
-{
-    m_listeners.add(listener);
-}
-
-void AudioSession::removeListener(AudioSessionListener* listener)
-{
-    m_listeners.remove(listener);
-}
-
-void AudioSession::beganAudioInterruption()
-{
-    for (HashSet<AudioSessionListener*>::iterator i = m_listeners.begin(); i != m_listeners.end(); ++i)
-        (*i)->beganAudioInterruption();
-}
-
-void AudioSession::endedAudioInterruption()
-{
-    for (HashSet<AudioSessionListener*>::iterator i = m_listeners.begin(); i != m_listeners.end(); ++i)
-        (*i)->endedAudioInterruption();
-}
-
 #if !PLATFORM(COCOA)
 class AudioSessionPrivate {
 };
 #if !PLATFORM(COCOA)
 class AudioSessionPrivate {
 };
index 4fff5a66847be828cf8005b3e2e63e0ac51066d5..b99f793f62ced309a17bdb8980c0da1da630f136 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,7 +34,6 @@
 
 namespace WebCore {
 
 
 namespace WebCore {
 
-class AudioSessionListener;
 class AudioSessionPrivate;
 
 class AudioSession {
 class AudioSessionPrivate;
 
 class AudioSession {
@@ -57,9 +56,6 @@ public:
     void setCategoryOverride(CategoryType);
     CategoryType categoryOverride() const;
 
     void setCategoryOverride(CategoryType);
     CategoryType categoryOverride() const;
 
-    void addListener(AudioSessionListener*);
-    void removeListener(AudioSessionListener*);
-
     float sampleRate() const;
     size_t numberOfOutputChannels() const;
 
     float sampleRate() const;
     size_t numberOfOutputChannels() const;
 
@@ -68,15 +64,11 @@ public:
     size_t preferredBufferSize() const;
     void setPreferredBufferSize(size_t);
 
     size_t preferredBufferSize() const;
     void setPreferredBufferSize(size_t);
 
-    void beganAudioInterruption();
-    void endedAudioInterruption();
-
 private:
     AudioSession();
     ~AudioSession();
 
     std::unique_ptr<AudioSessionPrivate> m_private;
 private:
     AudioSession();
     ~AudioSession();
 
     std::unique_ptr<AudioSessionPrivate> m_private;
-    HashSet<AudioSessionListener*> m_listeners;
 };
 
 }
 };
 
 }
diff --git a/Source/WebCore/platform/audio/AudioSessionListener.h b/Source/WebCore/platform/audio/AudioSessionListener.h
deleted file mode 100644 (file)
index f25551a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AudioSessionListener_h
-#define AudioSessionListener_h
-
-#if USE(AUDIO_SESSION)
-
-#include <wtf/Noncopyable.h>
-
-namespace WebCore {
-
-class AudioSessionListener {
-    WTF_MAKE_NONCOPYABLE(AudioSessionListener);
-public:
-    virtual void beganAudioInterruption() = 0;
-    virtual void endedAudioInterruption() = 0;
-protected:
-    AudioSessionListener() { }
-    virtual ~AudioSessionListener() { }
-};
-
-}
-
-#endif // USE(AUDIO_SESSION)
-
-#endif // AudioSessionListener_h
index 1c0e7ae3a77e00e6dacf053307e968b19a2cfe7c..679757a7bf89a469be72ed2501e23684bc824018 100644 (file)
@@ -119,11 +119,15 @@ void MediaSessionManager::addSession(MediaSession& session)
     m_sessions.append(&session);
     if (m_interrupted)
         session.setState(MediaSession::Interrupted);
     m_sessions.append(&session);
     if (m_interrupted)
         session.setState(MediaSession::Interrupted);
-    updateSessionState();
 
     if (!m_remoteCommandListener)
         m_remoteCommandListener = RemoteCommandListener::create(*this);
 
 
     if (!m_remoteCommandListener)
         m_remoteCommandListener = RemoteCommandListener::create(*this);
 
+    if (!m_audioHardwareListener)
+        m_audioHardwareListener = AudioHardwareListener::create(*this);
+
+    updateSessionState();
+
     if (m_clients.isEmpty() || !(session.mediaType() == MediaSession::Video || session.mediaType() == MediaSession::Audio))
         return;
 
     if (m_clients.isEmpty() || !(session.mediaType() == MediaSession::Video || session.mediaType() == MediaSession::Audio))
         return;
 
@@ -141,10 +145,13 @@ void MediaSessionManager::removeSession(MediaSession& session)
         return;
     
     m_sessions.remove(index);
         return;
     
     m_sessions.remove(index);
-    updateSessionState();
 
 
-    if (m_sessions.isEmpty())
+    if (m_sessions.isEmpty()) {
         m_remoteCommandListener = nullptr;
         m_remoteCommandListener = nullptr;
+        m_audioHardwareListener = nullptr;
+    }
+
+    updateSessionState();
 
     if (m_clients.isEmpty() || !(session.mediaType() == MediaSession::Video || session.mediaType() == MediaSession::Audio))
         return;
 
     if (m_clients.isEmpty() || !(session.mediaType() == MediaSession::Video || session.mediaType() == MediaSession::Audio))
         return;
@@ -339,6 +346,11 @@ void MediaSessionManager::systemDidWake()
         session->endInterruption(MediaSession::MayResumePlaying);
 }
 
         session->endInterruption(MediaSession::MayResumePlaying);
 }
 
+void MediaSessionManager::audioOutputDeviceChanged()
+{
+    updateSessionState();
+}
+
 }
 
 #endif
 }
 
 #endif
index 579bd9586dd6e1918192cccce4bc679cfcfdb548..b3ff9f946be0893b9f8ffb6a65bd2c7f9602845e 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef MediaSessionManager_h
 #define MediaSessionManager_h
 
 #ifndef MediaSessionManager_h
 #define MediaSessionManager_h
 
+#include <AudioHardwareListener.h>
 #include "MediaSession.h"
 #include "RemoteCommandListener.h"
 #include "Settings.h"
 #include "MediaSession.h"
 #include "RemoteCommandListener.h"
 #include "Settings.h"
@@ -52,7 +53,7 @@ protected:
     MediaSessionManagerClient() { }
 };
 
     MediaSessionManagerClient() { }
 };
 
-class MediaSessionManager : RemoteCommandListenerClient, SystemSleepListener::Client {
+class MediaSessionManager : private RemoteCommandListenerClient, private SystemSleepListener::Client, private AudioHardwareListener::Client {
 public:
     static MediaSessionManager& sharedManager();
     virtual ~MediaSessionManager() { }
 public:
     static MediaSessionManager& sharedManager();
     virtual ~MediaSessionManager() { }
@@ -94,8 +95,6 @@ public:
     virtual void stopMonitoringAirPlayRoutes() { }
 #endif
 
     virtual void stopMonitoringAirPlayRoutes() { }
 #endif
 
-    virtual void didReceiveRemoteControlCommand(MediaSession::RemoteControlCommandType) override;
-
     void addClient(MediaSessionManagerClient*);
     void removeClient(MediaSessionManagerClient*);
 
     void addClient(MediaSessionManagerClient*);
     void removeClient(MediaSessionManagerClient*);
 
@@ -114,8 +113,18 @@ private:
 
     void updateSessionState();
 
 
     void updateSessionState();
 
-    virtual void systemWillSleep();
-    virtual void systemDidWake();
+
+    // RemoteCommandListenerClient
+    virtual void didReceiveRemoteControlCommand(MediaSession::RemoteControlCommandType) override;
+
+    // AudioHardwareListenerClient
+    virtual void audioHardwareDidBecomeActive() override { }
+    virtual void audioHardwareDidBecomeInactive() override { }
+    virtual void audioOutputDeviceChanged() override;
+
+    // SystemSleepListener
+    virtual void systemWillSleep() override;
+    virtual void systemDidWake() override;
 
     SessionRestrictions m_restrictions[MediaSession::WebAudio + 1];
 
 
     SessionRestrictions m_restrictions[MediaSession::WebAudio + 1];
 
@@ -123,6 +132,7 @@ private:
     Vector<MediaSessionManagerClient*> m_clients;
     std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;
     std::unique_ptr<SystemSleepListener> m_systemSleepListener;
     Vector<MediaSessionManagerClient*> m_clients;
     std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;
     std::unique_ptr<SystemSleepListener> m_systemSleepListener;
+    RefPtr<AudioHardwareListener> m_audioHardwareListener;
     bool m_interrupted;
 };
 
     bool m_interrupted;
 };
 
index 807b8ba0c5b7a23660aa0b3dceb018c203ea3339..9b7646d84a733396bd739d43d98c610e62c033d1 100644 (file)
@@ -32,7 +32,6 @@
 
 #include "AudioBus.h"
 #include "AudioDestination.h"
 
 #include "AudioBus.h"
 #include "AudioDestination.h"
-#include "AudioSessionListener.h"
 #include "MediaSession.h"
 #include <AudioUnit/AudioUnit.h>
 #include <wtf/RefPtr.h>
 #include "MediaSession.h"
 #include <AudioUnit/AudioUnit.h>
 #include <wtf/RefPtr.h>
index 42658aa5b51d27821b8bc31f37dc49fd6e64841c..ffe97bc78a1b84296ccb9d166cc6f558b0cb85f2 100644 (file)
@@ -54,58 +54,8 @@ SOFT_LINK_POINTER(AVFoundation, AVAudioSessionInterruptionTypeKey, NSString *)
 #define AVAudioSessionCategoryAudioProcessing getAVAudioSessionCategoryAudioProcessing()
 #define AVAudioSessionInterruptionTypeKey getAVAudioSessionInterruptionTypeKey()
 
 #define AVAudioSessionCategoryAudioProcessing getAVAudioSessionCategoryAudioProcessing()
 #define AVAudioSessionInterruptionTypeKey getAVAudioSessionInterruptionTypeKey()
 
-static NSString * const WCAVAudioSessionInterruptionNotification = @"AVAudioSessionInterruptionNotification";
-
-#if !ASSERT_DISABLED
-SOFT_LINK_POINTER(AVFoundation, AVAudioSessionInterruptionNotification, NSString *)
-#endif
-
-@interface WebAudioSessionHelper : NSObject {
-    WebCore::AudioSession* _callback;
-}
-- (id)initWithCallback:(WebCore::AudioSession*)callback;
-- (void)interruption:(NSNotification*)notification;
-@end
-
-@implementation WebAudioSessionHelper
-- (id)initWithCallback:(WebCore::AudioSession*)callback
-{
-    self = [super init];
-    if (!self)
-        return nil;
-
-    _callback = callback;
-
-    ASSERT([WCAVAudioSessionInterruptionNotification isEqualToString:getAVAudioSessionInterruptionNotification()]);
-
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:WCAVAudioSessionInterruptionNotification object:nil];
-
-    return self;
-}
-
-- (void)dealloc
-{
-    [[NSNotificationCenter defaultCenter] removeObserver:self name:WCAVAudioSessionInterruptionNotification object:nil];
-    [super dealloc];
-}
-
-- (void)interruption:(NSNotification *)notification
-{
-    ASSERT([AVAudioSession sharedInstance] == [notification object]);
-    if ([AVAudioSession sharedInstance] != [notification object])
-        return;
-
-    NSUInteger type = [[[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
-    if (type == AVAudioSessionInterruptionTypeBegan)
-        _callback->beganAudioInterruption();
-    else
-        _callback->endedAudioInterruption();
-}
-@end
-
 namespace WebCore {
 
 namespace WebCore {
 
-
 #if !LOG_DISABLED
 static const char* categoryName(AudioSession::CategoryType category)
 {
 #if !LOG_DISABLED
 static const char* categoryName(AudioSession::CategoryType category)
 {
@@ -128,13 +78,11 @@ static const char* categoryName(AudioSession::CategoryType category)
 class AudioSessionPrivate {
 public:
     AudioSessionPrivate(AudioSession*);
 class AudioSessionPrivate {
 public:
     AudioSessionPrivate(AudioSession*);
-    RetainPtr<WebAudioSessionHelper> m_helper;
     AudioSession::CategoryType m_categoryOverride;
 };
 
     AudioSession::CategoryType m_categoryOverride;
 };
 
-AudioSessionPrivate::AudioSessionPrivate(AudioSession* session)
-    : m_helper(adoptNS([[WebAudioSessionHelper alloc] initWithCallback:session]))
-    , m_categoryOverride(AudioSession::None)
+AudioSessionPrivate::AudioSessionPrivate(AudioSession*)
+    : m_categoryOverride(AudioSession::None)
 {
 }
 
 {
 }
 
index 02b5ff7387ceba22ea9378797802fa1748fd856f..593bf310a48e5078daa1a67c6d17e7c781971893 100644 (file)
@@ -58,7 +58,57 @@ static AudioHardwareActivityType isAudioHardwareProcessRunning()
     else
         return AudioHardwareActivityType::IsInactive;
 }
     else
         return AudioHardwareActivityType::IsInactive;
 }
-    
+
+static bool currentDeviceSupportsLowPowerBufferSize()
+{
+    AudioDeviceID deviceID = kAudioDeviceUnknown;
+    UInt32 descriptorSize = sizeof(deviceID);
+    AudioObjectPropertyAddress defaultOutputDeviceDescriptor = {
+        kAudioHardwarePropertyDefaultOutputDevice,
+        kAudioObjectPropertyScopeGlobal,
+        kAudioObjectPropertyElementMaster };
+
+    if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &defaultOutputDeviceDescriptor, 0, 0, &descriptorSize, (void*)&deviceID))
+        return false;
+
+    UInt32 transportType = kAudioDeviceTransportTypeUnknown;
+    descriptorSize = sizeof(transportType);
+    AudioObjectPropertyAddress tranportTypeDescriptor = {
+        kAudioDevicePropertyTransportType,
+        kAudioObjectPropertyScopeGlobal,
+        kAudioObjectPropertyElementMaster,
+    };
+
+    if (AudioObjectGetPropertyData(deviceID, &tranportTypeDescriptor, 0, 0, &descriptorSize, &transportType))
+        return false;
+
+    // Only allow low-power buffer size when using built-in output device, many external devices perform
+    // poorly with a large output buffer.
+    return kAudioDeviceTransportTypeBuiltIn == transportType;
+}
+
+static const AudioObjectPropertyAddress& processIsRunningPropertyDescriptor()
+{
+    static AudioObjectPropertyAddress processIsRunningProperty = {
+        kAudioHardwarePropertyProcessIsRunning,
+        kAudioObjectPropertyScopeGlobal,
+        kAudioObjectPropertyElementMaster
+    };
+
+    return processIsRunningProperty;
+};
+
+static const AudioObjectPropertyAddress& outputDevicePropertyDescriptor()
+{
+    static AudioObjectPropertyAddress outputDeviceProperty = {
+        kAudioHardwarePropertyDefaultOutputDevice,
+        kAudioObjectPropertyScopeGlobal,
+        kAudioObjectPropertyElementMaster
+    };
+
+    return outputDeviceProperty;
+};
+
 PassRefPtr<AudioHardwareListener> AudioHardwareListener::create(Client& client)
 {
     return AudioHardwareListenerMac::create(client);
 PassRefPtr<AudioHardwareListener> AudioHardwareListener::create(Client& client)
 {
     return AudioHardwareListenerMac::create(client);
@@ -72,44 +122,45 @@ PassRefPtr<AudioHardwareListenerMac> AudioHardwareListenerMac::create(Client& cl
 AudioHardwareListenerMac::AudioHardwareListenerMac(Client& client)
     : AudioHardwareListener(client)
 {
 AudioHardwareListenerMac::AudioHardwareListenerMac(Client& client)
     : AudioHardwareListener(client)
 {
-    m_activity = isAudioHardwareProcessRunning();
-    if (hardwareActivity() == AudioHardwareActivityType::Unknown)
-        return;
-
-    AudioObjectPropertyAddress propertyAddress = {
-        kAudioHardwarePropertyProcessIsRunning,
-        kAudioObjectPropertyScopeGlobal,
-        kAudioObjectPropertyElementMaster
-    };
+    setHardwareActivity(isAudioHardwareProcessRunning());
+    setOutputDeviceSupportsLowPowerMode(currentDeviceSupportsLowPowerBufferSize());
 
 
-    m_block = Block_copy(^(UInt32, const AudioObjectPropertyAddress[]) {
-        setHardwareActive(isAudioHardwareProcessRunning());
+    m_block = Block_copy(^(UInt32 count, const AudioObjectPropertyAddress properties[]) {
+        propertyChanged(count, properties);
     });
 
     });
 
-    AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, &propertyAddress, dispatch_get_main_queue(), m_block);
+    AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, &processIsRunningPropertyDescriptor(), dispatch_get_main_queue(), m_block);
+    AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, &outputDevicePropertyDescriptor(), dispatch_get_main_queue(), m_block);
 }
 
 AudioHardwareListenerMac::~AudioHardwareListenerMac()
 {
 }
 
 AudioHardwareListenerMac::~AudioHardwareListenerMac()
 {
-    if (hardwareActivity() == AudioHardwareActivityType::Unknown)
-        return;
-    
-    AudioObjectPropertyAddress propertyAddress = {
-        kAudioHardwarePropertyProcessIsRunning,
-        kAudioObjectPropertyScopeGlobal,
-        kAudioObjectPropertyElementMaster
-    };
+    AudioObjectRemovePropertyListenerBlock(kAudioObjectSystemObject, &processIsRunningPropertyDescriptor(), dispatch_get_main_queue(), m_block);
+    AudioObjectRemovePropertyListenerBlock(kAudioObjectSystemObject, &outputDevicePropertyDescriptor(), dispatch_get_main_queue(), m_block);
+    Block_release(m_block);
+}
 
 
-    AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, &propertyAddress, dispatch_get_main_queue(), m_block);
+void AudioHardwareListenerMac::propertyChanged(UInt32 propertyCount, const AudioObjectPropertyAddress properties[])
+{
+    const AudioObjectPropertyAddress& deviceRunning = processIsRunningPropertyDescriptor();
+    const AudioObjectPropertyAddress& outputDevice = outputDevicePropertyDescriptor();
 
 
-    Block_release(m_block);
+    for (UInt32 i = 0; i < propertyCount; ++i) {
+        const AudioObjectPropertyAddress& property = properties[i];
+
+        if (!memcmp(&property, &deviceRunning, sizeof(AudioObjectPropertyAddress)))
+            processIsRunningChanged();
+        else if (!memcmp(&property, &outputDevice, sizeof(AudioObjectPropertyAddress)))
+            outputDeviceChanged();
+    }
 }
 
 }
 
-void AudioHardwareListenerMac::setHardwareActive(AudioHardwareActivityType activity)
+void AudioHardwareListenerMac::processIsRunningChanged()
 {
 {
-    if (activity == m_activity)
+    AudioHardwareActivityType activity = isAudioHardwareProcessRunning();
+    if (activity == hardwareActivity())
         return;
         return;
-    m_activity = activity;
+    setHardwareActivity(activity);
     
     if (hardwareActivity() == AudioHardwareActivityType::IsActive)
         m_client.audioHardwareDidBecomeActive();
     
     if (hardwareActivity() == AudioHardwareActivityType::IsActive)
         m_client.audioHardwareDidBecomeActive();
@@ -117,6 +168,12 @@ void AudioHardwareListenerMac::setHardwareActive(AudioHardwareActivityType activ
         m_client.audioHardwareDidBecomeInactive();
 }
 
         m_client.audioHardwareDidBecomeInactive();
 }
 
+void AudioHardwareListenerMac::outputDeviceChanged()
+{
+    setOutputDeviceSupportsLowPowerMode(currentDeviceSupportsLowPowerBufferSize());
+    m_client.audioOutputDeviceChanged();
+}
+
 }
 
 #endif
 }
 
 #endif
index 90248ecebee7232ba19e73751002f95fa310b5e7..6840f1ea6238724523d59b17241115a7c221b258 100644 (file)
@@ -38,11 +38,15 @@ class AudioHardwareListenerMac : public AudioHardwareListener {
 public:
     static WTF::PassRefPtr<AudioHardwareListenerMac> create(Client&);
 
 public:
     static WTF::PassRefPtr<AudioHardwareListenerMac> create(Client&);
 
-protected:
+private:
     AudioHardwareListenerMac(Client&);
     virtual ~AudioHardwareListenerMac();
 
     AudioHardwareListenerMac(Client&);
     virtual ~AudioHardwareListenerMac();
 
-    void setHardwareActive(AudioHardwareActivityType);
+    void processIsRunningChanged();
+    void outputDeviceChanged();
+
+    void propertyChanged(UInt32, const AudioObjectPropertyAddress[]);
+
     AudioObjectPropertyListenerBlock m_block;
 };
 
     AudioObjectPropertyListenerBlock m_block;
 };
 
index 26b8b17717035fd0e4865943555ffb9fd4876ec2..da6c1b50ac0706bfb484868a512e54e4a626be97 100644 (file)
@@ -50,7 +50,14 @@ void MediaSessionManager::updateSessionState()
     else if ((has(MediaSession::Video) || has(MediaSession::Audio)) && Settings::lowPowerVideoAudioBufferSizeEnabled()) {
         // FIXME: <http://webkit.org/b/116725> Figure out why enabling the code below
         // causes media LayoutTests to fail on 10.8.
     else if ((has(MediaSession::Video) || has(MediaSession::Audio)) && Settings::lowPowerVideoAudioBufferSizeEnabled()) {
         // FIXME: <http://webkit.org/b/116725> Figure out why enabling the code below
         // causes media LayoutTests to fail on 10.8.
-        AudioSession::sharedSession().setPreferredBufferSize(kLowPowerVideoBufferSize);
+
+        size_t bufferSize;
+        if (m_audioHardwareListener && m_audioHardwareListener->outputDeviceSupportsLowPowerMode())
+            bufferSize = kLowPowerVideoBufferSize;
+        else
+            bufferSize = kWebAudioBufferSize;
+
+        AudioSession::sharedSession().setPreferredBufferSize(bufferSize);
     }
 #endif
 
     }
 #endif
 
index 1f1fc8737616bab40a63cbbf2a5edcc21a549900..ff41aed204f95cb3edb683c65ee7cc08f37cb639 100644 (file)
@@ -1,3 +1,13 @@
+2014-07-14  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] don't enable low power audio mode on external output devices
+        https://bugs.webkit.org/show_bug.cgi?id=134877
+
+        Reviewed by Sam Weinig.
+
+        * PluginProcess/PluginProcess.h: Add an empty implementation of 
+            AudioHardwareListener::audioOutputDeviceChanged.
+
 2014-07-14  Tim Horton  <timothy_horton@apple.com>
 
         [iOS] Throttle painting using a UI-process-side CADisplayLink
 2014-07-14  Tim Horton  <timothy_horton@apple.com>
 
         [iOS] Throttle painting using a UI-process-side CADisplayLink
index d528eddb5c77d4c56992dfd5eb8b5aa01e220244..944239ac33ebface7a9feb029adfb19417dbcf97 100644 (file)
@@ -101,6 +101,7 @@ private:
     // AudioHardwareListenerClient
     virtual void audioHardwareDidBecomeActive() override;
     virtual void audioHardwareDidBecomeInactive() override;
     // AudioHardwareListenerClient
     virtual void audioHardwareDidBecomeActive() override;
     virtual void audioHardwareDidBecomeInactive() override;
+    virtual void audioOutputDeviceChanged() override { }
 
     void platformInitializePluginProcess(const PluginProcessCreationParameters&);
     
 
     void platformInitializePluginProcess(const PluginProcessCreationParameters&);