Title: [147494] trunk/Source/WebCore
Revision
147494
Author
[email protected]
Date
2013-04-02 13:49:19 -0700 (Tue, 02 Apr 2013)

Log Message

Add platform AudioSession and iOS platform-specific code.
https://bugs.webkit.org/show_bug.cgi?id=113813
<rdar://problem/11701792>

Reviewed by Eric Carlson.

Replace the deprecated AudioToolbox AudioSession APIs with the new AVAudioSession API.
To protect against exposing platform specific intrinsics to cross-platform code, add a
platform generic class AudioSession, with port-specific implementations. A default
implementation is provided.

Add a new listener interface to receive interruption notifications:
* platform/audio/AudioSessionListener.h: Added.
(WebCore::AudioSessionListener::AudioSessionListener):
(WebCore::AudioSessionListener::~AudioSessionListener):

Add a platform generic AudioSession class:
* platform/audio/AudioSession.cpp: Added.
(AudioSession::sharedSession): AudioSession is a singleton object, and this is its accessor.
(AudioSession::addListener): Add the parameter to the listeners set.
(AudioSession::removeListener): Remove the parameter from the listers set.
(AudioSession::beganAudioInterruption): Iterate over the parameters.
(AudioSession::endedAudioInterruption): Ditto.
(AudioSession::AudioSession): Empty stub.
(AudioSession::~AudioSession): Ditto.
(AudioSession::setCategory): Ditto.
(AudioSession::category): Ditto.
(AudioSession::sampleRate): Ditto.
(AudioSession::numberOfOutputChannels): Ditto.
(AudioSession::setActive): Ditto.
(AudioSession::preferredBufferDuration): Ditto.
(AudioSession::setPreferredBufferDuration): Ditto.
* platform/audio/AudioSession.h: Added.

Add IOS-specific AudioSession implementation:
* platform/audio/ios/AudioSessionIOS.mm: Added.
(-[WebAudioSessionHelper initWithCallback:WebCore::]): Register for interruption notifications.
(-[WebAudioSessionHelper dealloc]): Unregister for interruption notifications.
(-[WebAudioSessionHelper interruption:]): Pass to AudioSession.
(WebCore::AudioSessionPrivate::AudioSessionPrivate): Private storage for AudioSessionIOS.
(WebCore::AudioSession::AudioSession): Create AudioSessionPrivate and WebAudioSessionHelper.
(WebCore::AudioSession::~AudioSession): Simple destructor.
(WebCore::AudioSession::setCategory): Check the current categoryOverride, and refuse to overwrite
    "MediaPlayback" with "AmbientSound".
(WebCore::AudioSession::setCategoryOverride): Simple setter.
(WebCore::AudioSession::categoryOverride): Simple getter.
(WebCore::AudioSession::category): Pass to AVAudioSession.
(WebCore::AudioSession::sampleRate): Ditto.
(WebCore::AudioSession::numberOfOutputChannels): Ditto.
(WebCore::AudioSession::setActive): Ditto.
(WebCore::AudioSession::preferredBufferDuration): Ditto.
(WebCore::AudioSession::setPreferredBufferDuration): Ditto.

Use the new AudioSession class in place of explicit AudioToolbox or AVAudioSession calls:
* platform/audio/ios/AudioDestinationIOS.cpp:
(WebCore::AudioDestination::hardwareSampleRate): Pass to AudioSession.
(WebCore::AudioDestination::maxChannelCount): Ditto.
(WebCore::AudioDestinationIOS::AudioDestinationIOS): Register for listeners and activate.
(WebCore::AudioDestinationIOS::~AudioDestinationIOS): Unregister and deactivate.
(WebCore::AudioDestinationIOS::configure): Use AudioSession to set the buffer length.
* platform/audio/ios/AudioDestinationIOS.h:

Add the new files to the project:
* WebCore.xcodeproj/project.pbxproj:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (147493 => 147494)


--- trunk/Source/WebCore/ChangeLog	2013-04-02 20:47:12 UTC (rev 147493)
+++ trunk/Source/WebCore/ChangeLog	2013-04-02 20:49:19 UTC (rev 147494)
@@ -1,5 +1,72 @@
 2013-04-02  Jer Noble  <[email protected]>
 
+        Add platform AudioSession and iOS platform-specific code.
+        https://bugs.webkit.org/show_bug.cgi?id=113813
+        <rdar://problem/11701792>
+
+        Reviewed by Eric Carlson.
+
+        Replace the deprecated AudioToolbox AudioSession APIs with the new AVAudioSession API.
+        To protect against exposing platform specific intrinsics to cross-platform code, add a
+        platform generic class AudioSession, with port-specific implementations. A default
+        implementation is provided.
+
+        Add a new listener interface to receive interruption notifications:
+        * platform/audio/AudioSessionListener.h: Added.
+        (WebCore::AudioSessionListener::AudioSessionListener):
+        (WebCore::AudioSessionListener::~AudioSessionListener):
+
+        Add a platform generic AudioSession class:
+        * platform/audio/AudioSession.cpp: Added.
+        (AudioSession::sharedSession): AudioSession is a singleton object, and this is its accessor.
+        (AudioSession::addListener): Add the parameter to the listeners set.
+        (AudioSession::removeListener): Remove the parameter from the listers set.
+        (AudioSession::beganAudioInterruption): Iterate over the parameters.
+        (AudioSession::endedAudioInterruption): Ditto.
+        (AudioSession::AudioSession): Empty stub.
+        (AudioSession::~AudioSession): Ditto.
+        (AudioSession::setCategory): Ditto.
+        (AudioSession::category): Ditto.
+        (AudioSession::sampleRate): Ditto.
+        (AudioSession::numberOfOutputChannels): Ditto.
+        (AudioSession::setActive): Ditto.
+        (AudioSession::preferredBufferDuration): Ditto.
+        (AudioSession::setPreferredBufferDuration): Ditto.
+        * platform/audio/AudioSession.h: Added.
+
+        Add IOS-specific AudioSession implementation:
+        * platform/audio/ios/AudioSessionIOS.mm: Added.
+        (-[WebAudioSessionHelper initWithCallback:WebCore::]): Register for interruption notifications.
+        (-[WebAudioSessionHelper dealloc]): Unregister for interruption notifications.
+        (-[WebAudioSessionHelper interruption:]): Pass to AudioSession.
+        (WebCore::AudioSessionPrivate::AudioSessionPrivate): Private storage for AudioSessionIOS.
+        (WebCore::AudioSession::AudioSession): Create AudioSessionPrivate and WebAudioSessionHelper.
+        (WebCore::AudioSession::~AudioSession): Simple destructor.
+        (WebCore::AudioSession::setCategory): Check the current categoryOverride, and refuse to overwrite
+            "MediaPlayback" with "AmbientSound".
+        (WebCore::AudioSession::setCategoryOverride): Simple setter.
+        (WebCore::AudioSession::categoryOverride): Simple getter.
+        (WebCore::AudioSession::category): Pass to AVAudioSession.
+        (WebCore::AudioSession::sampleRate): Ditto.
+        (WebCore::AudioSession::numberOfOutputChannels): Ditto.
+        (WebCore::AudioSession::setActive): Ditto.
+        (WebCore::AudioSession::preferredBufferDuration): Ditto.
+        (WebCore::AudioSession::setPreferredBufferDuration): Ditto.
+
+        Use the new AudioSession class in place of explicit AudioToolbox or AVAudioSession calls:
+        * platform/audio/ios/AudioDestinationIOS.cpp:
+        (WebCore::AudioDestination::hardwareSampleRate): Pass to AudioSession.
+        (WebCore::AudioDestination::maxChannelCount): Ditto.
+        (WebCore::AudioDestinationIOS::AudioDestinationIOS): Register for listeners and activate.
+        (WebCore::AudioDestinationIOS::~AudioDestinationIOS): Unregister and deactivate.
+        (WebCore::AudioDestinationIOS::configure): Use AudioSession to set the buffer length.
+        * platform/audio/ios/AudioDestinationIOS.h:
+
+        Add the new files to the project:
+        * WebCore.xcodeproj/project.pbxproj:
+
+2013-04-02  Jer Noble  <[email protected]>
+
         Upstream AudioDestinationIOS.
         https://bugs.webkit.org/show_bug.cgi?id=113806
 

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (147493 => 147494)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2013-04-02 20:47:12 UTC (rev 147493)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2013-04-02 20:49:19 UTC (rev 147494)
@@ -6037,6 +6037,9 @@
 		CD82030D1395AB6A00F956C6 /* WebVideoFullscreenHUDWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD8203091395AB6A00F956C6 /* WebVideoFullscreenHUDWindowController.mm */; };
 		CD8203101395ACE700F956C6 /* WebWindowAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = CD82030E1395ACE700F956C6 /* WebWindowAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		CD8203111395ACE700F956C6 /* WebWindowAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD82030F1395ACE700F956C6 /* WebWindowAnimation.mm */; };
+		CDA79824170A258300D45C55 /* AudioSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDA79823170A258300D45C55 /* AudioSession.cpp */; };
+		CDA79827170A279100D45C55 /* AudioSessionIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDA79825170A279000D45C55 /* AudioSessionIOS.mm */; };
+		CDA7982A170A3D0000D45C55 /* AudioSession.h in Headers */ = {isa = PBXBuildFile; fileRef = CDA79821170A22DC00D45C55 /* AudioSession.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		CDA98DA31601464100FEA3B1 /* JSMediaKeyError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDA98D9B160128A500FEA3B1 /* JSMediaKeyError.cpp */; };
 		CDA98DD816025BEF00FEA3B1 /* MediaKeyMessageEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDA98DD516025BED00FEA3B1 /* MediaKeyMessageEvent.cpp */; };
 		CDA98DDF16026A3700FEA3B1 /* JSMediaKeyMessageEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDA98DDB16026A1800FEA3B1 /* JSMediaKeyMessageEvent.cpp */; };
@@ -13724,6 +13727,10 @@
 		CD8203091395AB6A00F956C6 /* WebVideoFullscreenHUDWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebVideoFullscreenHUDWindowController.mm; sourceTree = "<group>"; };
 		CD82030E1395ACE700F956C6 /* WebWindowAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebWindowAnimation.h; sourceTree = "<group>"; };
 		CD82030F1395ACE700F956C6 /* WebWindowAnimation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebWindowAnimation.mm; 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>"; };
 		CDA98D9C160128A500FEA3B1 /* JSMediaKeyError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaKeyError.h; sourceTree = "<group>"; };
 		CDA98DC216014EEE00FEA3B1 /* MediaKeyNeededEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MediaKeyNeededEvent.cpp; path = Modules/encryptedmedia/MediaKeyNeededEvent.cpp; sourceTree = "<group>"; };
@@ -21887,6 +21894,7 @@
 			children = (
 				CD0EEE0B14743E35003EAFA2 /* AudioDestinationIOS.cpp */,
 				CD0EEE0A14743E34003EAFA2 /* AudioDestinationIOS.h */,
+				CDA79825170A279000D45C55 /* AudioSessionIOS.mm */,
 			);
 			name = ios;
 			sourceTree = "<group>";
@@ -23222,6 +23230,9 @@
 				FD31605012B026F700C1A359 /* AudioResampler.h */,
 				FD31605112B026F700C1A359 /* AudioResamplerKernel.cpp */,
 				FD31605212B026F700C1A359 /* AudioResamplerKernel.h */,
+				CDA79821170A22DC00D45C55 /* AudioSession.h */,
+				CDA79823170A258300D45C55 /* AudioSession.cpp */,
+				CDA79822170A24F400D45C55 /* AudioSessionListener.h */,
 				FD31605312B026F700C1A359 /* AudioSourceProvider.h */,
 				FD62F52D145898D80094B0ED /* AudioSourceProviderClient.h */,
 				FD31605412B026F700C1A359 /* AudioUtilities.cpp */,
@@ -23472,6 +23483,7 @@
 				FD31608612B026F700C1A359 /* AudioResampler.h in Headers */,
 				FD31608812B026F700C1A359 /* AudioResamplerKernel.h in Headers */,
 				FD8C46EC154608E700A5910C /* AudioScheduledSourceNode.h in Headers */,
+				CDA7982A170A3D0000D45C55 /* AudioSession.h in Headers */,
 				FD31602212B0267600C1A359 /* AudioSourceNode.h in Headers */,
 				FD31608912B026F700C1A359 /* AudioSourceProvider.h in Headers */,
 				FD62F52E145898D80094B0ED /* AudioSourceProviderClient.h in Headers */,
@@ -27216,6 +27228,8 @@
 				FD31608512B026F700C1A359 /* AudioResampler.cpp in Sources */,
 				FD31608712B026F700C1A359 /* AudioResamplerKernel.cpp in Sources */,
 				FD8C46EB154608E700A5910C /* AudioScheduledSourceNode.cpp in Sources */,
+				CDA79824170A258300D45C55 /* AudioSession.cpp in Sources */,
+				CDA79827170A279100D45C55 /* AudioSessionIOS.mm in Sources */,
 				FDB052DF1561A42C00B500D6 /* AudioSummingJunction.cpp in Sources */,
 				FD31608A12B026F700C1A359 /* AudioUtilities.cpp in Sources */,
 				7EE6845F12D26E3800E79415 /* AuthenticationCF.cpp in Sources */,

Added: trunk/Source/WebCore/platform/audio/AudioSession.cpp (0 => 147494)


--- trunk/Source/WebCore/platform/audio/AudioSession.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/audio/AudioSession.cpp	2013-04-02 20:49:19 UTC (rev 147494)
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "AudioSession.h"
+
+#include "AudioSessionListener.h"
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+AudioSession& AudioSession::sharedSession()
+{
+    DEFINE_STATIC_LOCAL(AudioSession, 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(IOS)
+class AudioSessionPrivate {
+};
+
+AudioSession::AudioSession()
+    : m_private(0)
+{
+    notImplemented();
+}
+
+AudioSession::~AudioSession()
+{
+}
+
+void AudioSession::setCategory(CategoryType)
+{
+    notImplemented();
+}
+
+AudioSession::CategoryType AudioSession::categoryOverride() const
+{
+    notImplemented();
+    return None;
+}
+
+void AudioSession::setCategoryOverride(CategoryType)
+{
+    notImplemented();
+}
+
+AudioSession::CategoryType AudioSession::category() const
+{
+    notImplemented();
+    return None;
+}
+
+float AudioSession::sampleRate() const
+{
+    notImplemented();
+    return 0;
+}
+
+size_t AudioSession::numberOfOutputChannels() const
+{
+    notImplemented();
+    return 0;
+}
+
+void AudioSession::setActive(bool)
+{
+    notImplemented();
+}
+
+float AudioSession::preferredBufferDuration() const
+{
+    notImplemented();
+    return 0;
+}
+
+void AudioSession::setPreferredBufferDuration(float)
+{
+    notImplemented();
+}
+#endif // !PLATFORM(IOS)
+
+}

Added: trunk/Source/WebCore/platform/audio/AudioSession.h (0 => 147494)


--- trunk/Source/WebCore/platform/audio/AudioSession.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/audio/AudioSession.h	2013-04-02 20:49:19 UTC (rev 147494)
@@ -0,0 +1,81 @@
+/*
+ * 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 AudioSession_h
+#define AudioSession_h
+
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class AudioSessionListener;
+class AudioSessionPrivate;
+
+class AudioSession {
+    WTF_MAKE_NONCOPYABLE(AudioSession);
+public:
+    static AudioSession& sharedSession();
+
+    enum CategoryType {
+        None,
+        AmbientSound,
+        SoloAmbientSound,
+        MediaPlayback,
+        RecordAudio,
+        PlayAndRecord,
+        AudioProcessing,
+    };
+    void setCategory(CategoryType);
+    CategoryType category() const;
+
+    void setCategoryOverride(CategoryType);
+    CategoryType categoryOverride() const;
+
+    void addListener(AudioSessionListener*);
+    void removeListener(AudioSessionListener*);
+
+    float sampleRate() const;
+    size_t numberOfOutputChannels() const;
+
+    void setActive(bool);
+
+    float preferredBufferDuration() const;
+    void setPreferredBufferDuration(float seconds);
+
+    void beganAudioInterruption();
+    void endedAudioInterruption();
+
+private:
+    AudioSession();
+    ~AudioSession();
+
+    OwnPtr<AudioSessionPrivate> m_private;
+    HashSet<AudioSessionListener*> m_listeners;
+};
+
+}
+
+#endif // AudioSession_h

Added: trunk/Source/WebCore/platform/audio/AudioSessionListener.h (0 => 147494)


--- trunk/Source/WebCore/platform/audio/AudioSessionListener.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/audio/AudioSessionListener.h	2013-04-02 20:49:19 UTC (rev 147494)
@@ -0,0 +1,43 @@
+/*
+ * 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
+
+namespace WebCore {
+
+class AudioSessionListener {
+    WTF_MAKE_NONCOPYABLE(AudioSessionListener)
+public:
+    virtual void beganAudioInterruption() = 0;
+    virtual void endedAudioInterruption() = 0;
+protected:
+    AudioSessionListener() { }
+    virtual ~AudioSessionListener() { }
+};
+
+}
+
+#endif // AudioSessionListener_h

Modified: trunk/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp (147493 => 147494)


--- trunk/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp	2013-04-02 20:47:12 UTC (rev 147493)
+++ trunk/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp	2013-04-02 20:49:19 UTC (rev 147494)
@@ -36,11 +36,11 @@
 #include "AudioDestinationIOS.h"
 
 #include "AudioIOCallback.h"
+#include "AudioSession.h"
 #include "FloatConversion.h"
 #include "Logging.h"
 #include "Page.h"
 #include "SoftLinking.h"
-#include <CoreAudio/AudioHardware.h>
 #include <AudioToolbox/AudioServices.h>
 #include <WebCore/RuntimeApplicationChecksIOS.h>
 #include <wtf/HashSet.h>
@@ -51,10 +51,6 @@
 SOFT_LINK(AudioToolbox, AudioComponentInstanceNew, OSStatus, (AudioComponent inComponent, AudioComponentInstance *outInstance), (inComponent, outInstance))
 SOFT_LINK(AudioToolbox, AudioOutputUnitStart, OSStatus, (AudioUnit ci), (ci))
 SOFT_LINK(AudioToolbox, AudioOutputUnitStop, OSStatus, (AudioUnit ci), (ci))
-SOFT_LINK(AudioToolbox, AudioSessionInitialize, OSStatus, (CFRunLoopRef inRunLoop, CFStringRef inRunLoopMode, AudioSessionInterruptionListener inInterruptionListener, void *inClientData), (inRunLoop, inRunLoopMode, inInterruptionListener, inClientData))
-SOFT_LINK(AudioToolbox, AudioSessionGetProperty, OSStatus, (AudioSessionPropertyID inID, UInt32 *ioDataSize, void *outData), (inID, ioDataSize, outData))
-SOFT_LINK(AudioToolbox, AudioSessionSetActive, OSStatus, (Boolean active), (active))
-SOFT_LINK(AudioToolbox, AudioSessionSetProperty, OSStatus, (AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData), (inID, inDataSize, inData))
 SOFT_LINK(AudioToolbox, AudioUnitAddPropertyListener, OSStatus, (AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitPropertyListenerProc inProc, void *inProcUserData), (inUnit, inID, inProc, inProcUserData))
 SOFT_LINK(AudioToolbox, AudioUnitGetProperty, OSStatus, (AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void *outData, UInt32 *ioDataSize), (inUnit, inID, inScope, inElement, outData, ioDataSize))
 SOFT_LINK(AudioToolbox, AudioUnitInitialize, OSStatus, (AudioUnit inUnit), (inUnit))
@@ -88,20 +84,9 @@
     return adoptPtr(new AudioDestinationIOS(callback, sampleRate));
 }
 
-// iOS 7.0/Innsbruck will deprecate AudioSession APIs. For now continue to use the old API.
-// <rdar://problem/11701792> AudioSession should move to using AVAudioSession (Innsbruck)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
 float AudioDestination::hardwareSampleRate()
 {
-    AudioDestinationIOS::initializeAudioSession();
-
-    double sampleRate = 0;
-    UInt32 sampleRateSize = sizeof(sampleRate);
-
-    AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &sampleRateSize, &sampleRate);
-    return sampleRate;
+    return AudioSession::sharedSession().sampleRate();
 }
 
 unsigned long AudioDestination::maxChannelCount()
@@ -121,11 +106,13 @@
     , m_isPlaying(false)
     , m_interruptedOnPlayback(false)
 {
-    initializeAudioSession();
+    AudioSession& session = AudioSession::sharedSession();
+    session.addListener(this);
+    session.setCategory(AudioSession::AmbientSound);
 
     audioDestinations().add(this);
     if (audioDestinations().size() == 1)
-        AudioSessionSetActive(true);
+        session.setActive(1);
 
     // Open and initialize DefaultOutputUnit
     AudioComponent comp;
@@ -145,11 +132,11 @@
 
     UInt32 flag = 1;
     result = AudioUnitSetProperty(m_outputUnit, 
-                                  kAudioOutputUnitProperty_EnableIO, 
-                                  kAudioUnitScope_Output, 
-                                  0,
-                                  &flag, 
-                                  sizeof(flag));
+        kAudioOutputUnitProperty_EnableIO, 
+        kAudioUnitScope_Output, 
+        0,
+        &flag, 
+        sizeof(flag));
     ASSERT(!result);
 
     result = AudioUnitAddPropertyListener(m_outputUnit, kAudioUnitProperty_MaximumFramesPerSlice, frameSizeChangedProc, this);
@@ -164,8 +151,8 @@
 AudioDestinationIOS::~AudioDestinationIOS()
 {
     audioDestinations().remove(this);
-    if (audioDestinations().size() == 0)
-        AudioSessionSetActive(false);
+    if (!audioDestinations().size())
+        AudioSession::sharedSession().setActive(0);
 
     if (m_outputUnit)
         AudioComponentInstanceDispose(m_outputUnit);
@@ -201,34 +188,9 @@
     result = AudioUnitSetProperty(m_outputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, (void*)&streamFormat, sizeof(AudioStreamBasicDescription));
     ASSERT(!result);
 
-    Float32 duration = narrowPrecisionToFloat(kPreferredBufferSize / m_sampleRate);
-    AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(duration), &duration);
+    AudioSession::sharedSession().setPreferredBufferDuration(narrowPrecisionToFloat(kPreferredBufferSize / m_sampleRate));
 }
 
-void AudioDestinationIOS::audioDestinationInterruptionListener(void *userData, UInt32 interruptionState)
-{
-    ASSERT_UNUSED(userData, userData);
-    for (AudioDestinationSet::iterator i = audioDestinations().begin(); i != audioDestinations().end(); ++i) {
-        if (interruptionState == kAudioSessionBeginInterruption)
-            (*i)->beganAudioInterruption();
-        else
-            (*i)->endedAudioInterruption();
-    }
-}
-
-void AudioDestinationIOS::initializeAudioSession()
-{
-    static bool audioSessionWasInitialized = false;
-    if (audioSessionWasInitialized)
-        return;
-
-    audioSessionWasInitialized = true;
-    AudioSessionInitialize(0, 0, &audioDestinationInterruptionListener, 0);
-    Page::setAudioSessionCategory(kAudioSessionCategory_AmbientSound);
-}
-
-#pragma GCC diagnostic pop
-
 void AudioDestinationIOS::start()
 {
     OSStatus result = AudioOutputUnitStart(m_outputUnit);
@@ -268,7 +230,7 @@
 {
     AudioBuffer* buffers = ioData->mBuffers;
     for (UInt32 frameOffset = 0; frameOffset + kRenderBufferSize <= numberOfFrames; frameOffset += kRenderBufferSize) {
-        UInt32 remainingFrames = MIN(kRenderBufferSize, numberOfFrames - frameOffset);
+        UInt32 remainingFrames = std::min<UInt32>(kRenderBufferSize, numberOfFrames - frameOffset);
         for (UInt32 i = 0; i < ioData->mNumberBuffers; ++i) {
             UInt32 bytesPerFrame = buffers[i].mDataByteSize / numberOfFrames;
             UInt32 byteOffset = frameOffset * bytesPerFrame;

Added: trunk/Source/WebCore/platform/audio/ios/AudioSessionIOS.mm (0 => 147494)


--- trunk/Source/WebCore/platform/audio/ios/AudioSessionIOS.mm	                        (rev 0)
+++ trunk/Source/WebCore/platform/audio/ios/AudioSessionIOS.mm	2013-04-02 20:49:19 UTC (rev 147494)
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+#import "config.h"
+#import "AudioSession.h"
+
+#if PLATFORM(IOS)
+
+#import "SoftLinking.h"
+#import <AVFoundation/AVAudioSession.h>
+#import <objc/runtime.h>
+#import <wtf/RetainPtr.h>
+
+SOFT_LINK_FRAMEWORK(AVFoundation)
+SOFT_LINK_CLASS(AVFoundation, AVAudioSession)
+
+SOFT_LINK_POINTER(AVFoundation, AVAudioSessionCategoryAmbient, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVAudioSessionCategorySoloAmbient, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVAudioSessionCategoryPlayback, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVAudioSessionCategoryRecord, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVAudioSessionCategoryPlayAndRecord, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVAudioSessionCategoryAudioProcessing, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVAudioSessionInterruptionNotification, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVAudioSessionInterruptionTypeKey, NSString *)
+
+#define AVAudioSession getAVAudioSessionClass()
+#define AVAudioSessionCategoryAmbient getAVAudioSessionCategoryAmbient()
+#define AVAudioSessionCategorySoloAmbient getAVAudioSessionCategorySoloAmbient()
+#define AVAudioSessionCategoryPlayback getAVAudioSessionCategoryPlayback()
+#define AVAudioSessionCategoryRecord getAVAudioSessionCategoryRecord()
+#define AVAudioSessionCategoryPlayAndRecord getAVAudioSessionCategoryPlayAndRecord()
+#define AVAudioSessionCategoryAudioProcessing getAVAudioSessionCategoryAudioProcessing()
+#define AVAudioSessionInterruptionNotification getAVAudioSessionInterruptionNotification()
+#define AVAudioSessionInterruptionTypeKey getAVAudioSessionInterruptionTypeKey()
+
+@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;
+
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
+
+    return self;
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    [super dealloc];
+}
+
+- (void)interruption:(NSNotification *)notification
+{
+    NSUInteger type = [[[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
+    if (type == AVAudioSessionInterruptionTypeBegan)
+        _callback->beganAudioInterruption();
+    else
+        _callback->endedAudioInterruption();
+}
+@end
+
+namespace WebCore {
+
+class AudioSessionPrivate {
+public:
+    AudioSessionPrivate(AudioSession*);
+    RetainPtr<WebAudioSessionHelper> m_helper;
+    AudioSession::CategoryType m_categoryOverride;
+};
+
+AudioSessionPrivate::AudioSessionPrivate(AudioSession* session)
+    : m_helper(adoptNS([[WebAudioSessionHelper alloc] initWithCallback:session]))
+    , m_categoryOverride(AudioSession::None)
+{
+}
+
+AudioSession::AudioSession()
+    : m_private(adoptPtr(new AudioSessionPrivate(this)))
+{
+}
+
+AudioSession::~AudioSession()
+{
+}
+
+void AudioSession::setCategory(CategoryType newCategory)
+{
+    if (categoryOverride() && categoryOverride() != newCategory)
+        return;
+
+    if (!categoryOverride()) {
+        // If a page plays only WebAudio we set the audio category to "ambient" so it is muted by the ringer switch.
+        // However, audio from an HTML5 media element or from a plug-in should always play as "media" so don't change the
+        // category once it has already been set to media.
+        if (newCategory == AudioSession::AmbientSound && category() == AudioSession::MediaPlayback)
+            return;
+    }
+
+    NSString* categoryString;
+    switch (newCategory) {
+    case AmbientSound:
+        categoryString = AVAudioSessionCategoryAmbient;
+    case SoloAmbientSound:
+        categoryString = AVAudioSessionCategorySoloAmbient;
+    case MediaPlayback:
+        categoryString = AVAudioSessionCategoryPlayback;
+    case RecordAudio:
+        categoryString = AVAudioSessionCategoryRecord;
+    case PlayAndRecord:
+        categoryString = AVAudioSessionCategoryPlayAndRecord;
+    case AudioProcessing:
+        categoryString = AVAudioSessionCategoryAudioProcessing;
+    case None:
+    default:
+        categoryString = nil;
+    }
+    NSError *error = nil;
+    [[AVAudioSession sharedInstance] setCategory:categoryString error:error];
+    ASSERT(!error);
+}
+
+AudioSession::CategoryType AudioSession::category() const
+{
+    NSString* categoryString = [[AVAudioSession sharedInstance] category];
+    if ([categoryString isEqual:AVAudioSessionCategoryAmbient])
+        return AmbientSound;
+    if ([categoryString isEqual:AVAudioSessionCategorySoloAmbient])
+        return SoloAmbientSound;
+    if ([categoryString isEqual:AVAudioSessionCategoryPlayback])
+        return MediaPlayback;
+    if ([categoryString isEqual:AVAudioSessionCategoryRecord])
+        return RecordAudio;
+    if ([categoryString isEqual:AVAudioSessionCategoryPlayAndRecord])
+        return PlayAndRecord;
+    if ([categoryString isEqual:AVAudioSessionCategoryAudioProcessing])
+        return AudioProcessing;
+    return None;
+}
+
+void AudioSession::setCategoryOverride(CategoryType category)
+{
+    if (m_private->m_categoryOverride == category)
+        return;
+
+    m_private->m_categoryOverride = category;
+    setCategory(category);
+}
+
+AudioSession::CategoryType AudioSession::categoryOverride() const
+{
+    return m_private->m_categoryOverride;
+}
+
+float AudioSession::sampleRate() const
+{
+    return [[AVAudioSession sharedInstance] sampleRate];
+}
+
+size_t AudioSession::numberOfOutputChannels() const
+{
+    return [[AVAudioSession sharedInstance] outputNumberOfChannels];
+}
+
+void AudioSession::setActive(bool active)
+{
+    NSError *error = nil;
+    [[AVAudioSession sharedInstance] setActive:active error:&error];
+    ASSERT(!error);
+}
+
+float AudioSession::preferredBufferDuration() const
+{
+    return [[AVAudioSession sharedInstance] preferredIOBufferDuration];
+}
+
+void AudioSession::setPreferredBufferDuration(float duration)
+{
+    NSError *error = nil;
+    [[AVAudioSession sharedInstance] setPreferredIOBufferDuration:duration error:&error];
+    ASSERT(!error);
+}
+
+}
+
+#endif // PLATFORM(IOS)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to