⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 167767 in webkit


Ignore:
Timestamp:
Apr 24, 2014, 12:04:01 PM (12 years ago)
Author:
eric.carlson@apple.com
Message:

[iOS] Manage AudioSession category according to media type
https://bugs.webkit.org/show_bug.cgi?id=132096

Reviewed by Jer Noble.

Source/WebCore:

  • WebCore.exp.in: Export setting.
  • html/HTMLMediaSession.cpp:

(WebCore::HTMLMediaSession::HTMLMediaSession):
(WebCore::initializeAudioSession): Deleted.

  • page/Settings.cpp:
  • page/Settings.h:

(WebCore::Settings::setShouldManageAudioSession): New.
(WebCore::Settings::shouldManageAudioSession): Ditto.

  • platform/audio/ios/AudioDestinationIOS.cpp:

(WebCore::AudioDestinationIOS::AudioDestinationIOS): Use a MediaSession instead of inheriting

from AudioListener and calling the AudioSession directly.

(WebCore::AudioDestinationIOS::~AudioDestinationIOS): Ditto.
(WebCore::AudioDestinationIOS::start): Notify session.
(WebCore::AudioDestinationIOS::stop): Ditto.
(WebCore::AudioDestinationIOS::beganAudioInterruption): Deleted.
(WebCore::AudioDestinationIOS::endedAudioInterruption): Deleted.

  • platform/audio/ios/AudioDestinationIOS.h:

(WebCore::AudioDestinationIOS::mediaType):
(WebCore::AudioDestinationIOS::canReceiveRemoteControlCommands):
(WebCore::AudioDestinationIOS::didReceiveRemoteControlCommand):
(WebCore::AudioDestinationIOS::isPlaying): Deleted.

  • platform/audio/ios/AudioSessionIOS.mm:

(WebCore::categoryName): Debug-only logging function.
(WebCore::AudioSession::setCategory): Don't stick with "media" once it is set.

  • platform/audio/ios/MediaSessionManagerIOS.mm:

(WebCore::MediaSessionManageriOS::resetRestrictions): Set up restrictions for WebAudio.
(WebCore::MediaSessionManageriOS::updateNowPlayingInfo): Don't set invalid start time.

  • platform/audio/mac/MediaSessionManagerMac.cpp:

(MediaSessionManager::updateSessionState): Manage AudioSession.active when WebAudio clients

come and go. Manage AudioSession.category according to the number of WebAudio and
HTMLMediaElement clients.

Source/WebKit/mac:

  • WebView/WebView.mm:

(-[WebView _commonInitializationWithFrameName:groupName:]): Tell

WebCore to manage the AudioSession when running in MobileSafari.

Source/WebKit2:

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::WebPage): Tell WebCore to manage the AudioSession.

Location:
trunk/Source
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r167764 r167767  
     12014-04-24  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [iOS] Manage AudioSession category according to media type
     4        https://bugs.webkit.org/show_bug.cgi?id=132096
     5
     6        Reviewed by Jer Noble.
     7
     8        * WebCore.exp.in: Export setting.
     9
     10        * html/HTMLMediaSession.cpp:
     11        (WebCore::HTMLMediaSession::HTMLMediaSession):
     12        (WebCore::initializeAudioSession): Deleted.
     13
     14        * page/Settings.cpp:
     15        * page/Settings.h:
     16        (WebCore::Settings::setShouldManageAudioSession): New.
     17        (WebCore::Settings::shouldManageAudioSession): Ditto.
     18
     19        * platform/audio/ios/AudioDestinationIOS.cpp:
     20        (WebCore::AudioDestinationIOS::AudioDestinationIOS): Use a MediaSession instead of inheriting
     21            from AudioListener and calling the AudioSession directly.
     22        (WebCore::AudioDestinationIOS::~AudioDestinationIOS): Ditto.
     23        (WebCore::AudioDestinationIOS::start): Notify session.
     24        (WebCore::AudioDestinationIOS::stop): Ditto.
     25        (WebCore::AudioDestinationIOS::beganAudioInterruption): Deleted.
     26        (WebCore::AudioDestinationIOS::endedAudioInterruption): Deleted.
     27        * platform/audio/ios/AudioDestinationIOS.h:
     28        (WebCore::AudioDestinationIOS::mediaType):
     29        (WebCore::AudioDestinationIOS::canReceiveRemoteControlCommands):
     30        (WebCore::AudioDestinationIOS::didReceiveRemoteControlCommand):
     31        (WebCore::AudioDestinationIOS::isPlaying): Deleted.
     32
     33        * platform/audio/ios/AudioSessionIOS.mm:
     34        (WebCore::categoryName): Debug-only logging function.
     35        (WebCore::AudioSession::setCategory): Don't stick with "media" once it is set.
     36
     37        * platform/audio/ios/MediaSessionManagerIOS.mm:
     38        (WebCore::MediaSessionManageriOS::resetRestrictions): Set up restrictions for WebAudio.
     39        (WebCore::MediaSessionManageriOS::updateNowPlayingInfo): Don't set invalid start time.
     40
     41        * platform/audio/mac/MediaSessionManagerMac.cpp:
     42        (MediaSessionManager::updateSessionState): Manage AudioSession.active when WebAudio clients
     43            come and go. Manage AudioSession.category according to the number of WebAudio and
     44            HTMLMediaElement clients.
     45
    1462014-04-24  David Hyatt  <hyatt@apple.com>
    247
  • trunk/Source/WebCore/WebCore.exp.in

    r167735 r167767  
    26482648__ZN7WebCore8Settings13gAVKitEnabledE
    26492649__ZN7WebCore8Settings23setNetworkInterfaceNameERKN3WTF6StringE
     2650__ZN7WebCore8Settings19gManageAudioSessionE
    26502651__ZN7WebCore8Settings31setAudioSessionCategoryOverrideEj
    26512652__ZN7WebCore8Settings34setNetworkDataUsageTrackingEnabledEb
  • trunk/Source/WebCore/html/HTMLMediaSession.cpp

    r166384 r167767  
    7070#endif
    7171
    72 static void initializeAudioSession()
    73 {
    74 #if PLATFORM(IOS)
    75     static bool wasAudioSessionInitialized;
    76     if (wasAudioSessionInitialized)
    77         return;
    78 
    79     wasAudioSessionInitialized = true;
    80     if (!WebCore::applicationIsMobileSafari())
    81         return;
    82 
    83     AudioSession::sharedSession().setCategory(AudioSession::MediaPlayback);
    84 #endif
    85 }
    86 
    8772std::unique_ptr<HTMLMediaSession> HTMLMediaSession::create(MediaSessionClient& client)
    8873{
     
    9479    , m_restrictions(NoRestrictions)
    9580{
    96     initializeAudioSession();
    9781}
    9882
  • trunk/Source/WebCore/page/Settings.cpp

    r167522 r167767  
    101101bool Settings::gAVKitEnabled = false;
    102102bool Settings::gShouldOptOutOfNetworkStateObservation = false;
     103bool Settings::gManageAudioSession = false;
    103104#endif
    104105
  • trunk/Source/WebCore/page/Settings.h

    r166661 r167767  
    271271    static void setShouldOptOutOfNetworkStateObservation(bool flag) { gShouldOptOutOfNetworkStateObservation = flag; }
    272272    static bool shouldOptOutOfNetworkStateObservation() { return gShouldOptOutOfNetworkStateObservation; }
     273
     274    static void setShouldManageAudioSession(bool flag) { gManageAudioSession = flag; }
     275    static bool shouldManageAudioSession() { return gManageAudioSession; }
    273276#endif
    274277
     
    352355    static bool gAVKitEnabled;
    353356    static bool gShouldOptOutOfNetworkStateObservation;
     357    static bool gManageAudioSession;
    354358#endif
    355359
  • trunk/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp

    r165676 r167767  
    11/*
    22 * Copyright (C) 2010 Google Inc. All rights reserved.
    3  * Copyright (C) 2011 Apple Inc. All rights reserved.
     3 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    101101    , m_callback(callback)
    102102    , m_renderBus(AudioBus::create(2, kRenderBufferSize, false))
     103    , m_mediaSession(MediaSession::create(*this))
    103104    , m_sampleRate(sampleRate)
    104105    , m_isPlaying(false)
    105     , m_interruptedOnPlayback(false)
    106 {
    107     AudioSession& session = AudioSession::sharedSession();
    108     session.addListener(this);
    109     session.setCategory(AudioSession::AmbientSound);
    110 
     106{
    111107    audioDestinations().add(this);
    112     if (audioDestinations().size() == 1)
    113         session.setActive(1);
    114108
    115109    // Open and initialize DefaultOutputUnit
     
    149143AudioDestinationIOS::~AudioDestinationIOS()
    150144{
    151     AudioSession::sharedSession().removeListener(this);
    152145    audioDestinations().remove(this);
    153     if (!audioDestinations().size())
    154         AudioSession::sharedSession().setActive(0);
    155146
    156147    if (m_outputUnit)
     
    193184void AudioDestinationIOS::start()
    194185{
     186    LOG(Media, "AudioDestinationIOS::start");
     187    if (!m_mediaSession->clientWillBeginPlayback()) {
     188        LOG(Media, "  returning because of interruption");
     189        return;
     190    }
     191
    195192    OSStatus result = AudioOutputUnitStart(m_outputUnit);
    196 
    197193    if (!result)
    198194        m_isPlaying = true;
     
    201197void AudioDestinationIOS::stop()
    202198{
     199    LOG(Media, "AudioDestinationIOS::stop");
     200    if (!m_mediaSession->clientWillPausePlayback()) {
     201        LOG(Media, "  returning because of interruption");
     202        return;
     203    }
     204
    203205    OSStatus result = AudioOutputUnitStop(m_outputUnit);
    204 
    205206    if (!result)
    206207        m_isPlaying = false;
    207 }
    208 
    209 void AudioDestinationIOS::beganAudioInterruption()
    210 {
    211     if (!m_isPlaying)
    212         return;
    213 
    214     stop();
    215     m_interruptedOnPlayback = true;
    216 }
    217 
    218 void AudioDestinationIOS::endedAudioInterruption()
    219 {
    220     if (!m_interruptedOnPlayback)
    221         return;
    222 
    223     m_interruptedOnPlayback = false;
    224     start();
    225208}
    226209
  • trunk/Source/WebCore/platform/audio/ios/AudioDestinationIOS.h

    r165676 r167767  
    11/*
    22 * Copyright (C) 2010 Google Inc. All rights reserved.
    3  * Copyright (C) 2011 Apple Inc. All rights reserved.
     3 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    3434#include "AudioDestination.h"
    3535#include "AudioSessionListener.h"
     36#include "MediaSession.h"
    3637#include <AudioUnit/AudioUnit.h>
    3738#include <wtf/RefPtr.h>
     
    4142// An AudioDestination using CoreAudio's default output AudioUnit
    4243
    43 class AudioDestinationIOS : public AudioDestination, public AudioSessionListener {
     44class AudioDestinationIOS final : public AudioDestination, private MediaSessionClient {
    4445public:
    4546    AudioDestinationIOS(AudioIOCallback&, double sampleRate);
    4647    virtual ~AudioDestinationIOS();
    4748
    48     virtual void start();
    49     virtual void stop();
    50     bool isPlaying() { return m_isPlaying; }
    51 
    52     float sampleRate() const { return m_sampleRate; }
    53 
    5449private:
    5550    void configure();
    56     virtual void beganAudioInterruption() override;
    57     virtual void endedAudioInterruption() override;
     51
     52    // AudioDestination
     53    virtual void start() override;
     54    virtual void stop() override;
     55    virtual bool isPlaying() override { return m_isPlaying; }
     56    virtual float sampleRate() const override { return m_sampleRate; }
     57
     58    // MediaSessionClient
     59    virtual MediaSession::MediaType mediaType() const { return MediaSession::WebAudio; }
     60    virtual bool canReceiveRemoteControlCommands() const { return false; }
     61    virtual void didReceiveRemoteControlCommand(MediaSession::RemoteControlCommandType) { }
     62    virtual void pausePlayback() override { stop(); }
     63    virtual void resumePlayback() override { start(); }
    5864
    5965    // DefaultOutputUnit callback
     
    6874    AudioIOCallback& m_callback;
    6975    RefPtr<AudioBus> m_renderBus;
     76    std::unique_ptr<MediaSession> m_mediaSession;
    7077
    7178    double m_sampleRate;
    7279    bool m_isPlaying;
    73     bool m_interruptedOnPlayback;
    7480};
    7581
  • trunk/Source/WebCore/platform/audio/ios/AudioSessionIOS.mm

    r162368 r167767  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2929#if USE(AUDIO_SESSION) && PLATFORM(IOS)
    3030
     31#import "Logging.h"
    3132#import "SoftLinking.h"
    3233#import <AVFoundation/AVAudioSession.h>
     
    105106namespace WebCore {
    106107
     108
     109#if !LOG_DISABLED
     110static const char* categoryName(AudioSession::CategoryType category)
     111{
     112#define CASE(category) case AudioSession::category: return #category
     113    switch (category) {
     114        CASE(None);
     115        CASE(AmbientSound);
     116        CASE(SoloAmbientSound);
     117        CASE(MediaPlayback);
     118        CASE(RecordAudio);
     119        CASE(PlayAndRecord);
     120        CASE(AudioProcessing);
     121    }
     122   
     123    ASSERT_NOT_REACHED();
     124    return "";
     125}
     126#endif
     127
    107128class AudioSessionPrivate {
    108129public:
     
    129150void AudioSession::setCategory(CategoryType newCategory)
    130151{
    131     if (categoryOverride() && categoryOverride() != newCategory)
     152    LOG(Media, "AudioSession::setCategory() - category = %s", categoryName(newCategory));
     153
     154    if (categoryOverride() && categoryOverride() != newCategory) {
     155        LOG(Media, "AudioSession::setCategory() - override set, NOT changing");
    132156        return;
    133 
    134     if (!categoryOverride()) {
    135         // If a page plays only WebAudio we set the audio category to "ambient" so it is muted by the ringer switch.
    136         // However, audio from an HTML5 media element or from a plug-in should always play as "media" so don't change the
    137         // category once it has already been set to media.
    138         if (newCategory == AudioSession::AmbientSound && category() == AudioSession::MediaPlayback)
    139             return;
    140157    }
    141158
    142     NSString* categoryString;
     159    NSString *categoryString;
    143160    switch (newCategory) {
    144161    case AmbientSound:
     
    172189AudioSession::CategoryType AudioSession::category() const
    173190{
    174     NSString* categoryString = [[AVAudioSession sharedInstance] category];
     191    NSString *categoryString = [[AVAudioSession sharedInstance] category];
    175192    if ([categoryString isEqual:AVAudioSessionCategoryAmbient])
    176193        return AmbientSound;
  • trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm

    r166384 r167767  
    137137    addRestriction(MediaSession::Video, BackgroundPlaybackNotPermitted);
    138138
     139    removeRestriction(MediaSession::Audio, ConcurrentPlaybackNotPermitted);
     140    removeRestriction(MediaSession::Audio, BackgroundPlaybackNotPermitted);
     141
     142    removeRestriction(MediaSession::WebAudio, ConcurrentPlaybackNotPermitted);
     143    removeRestriction(MediaSession::WebAudio, BackgroundPlaybackNotPermitted);
     144
    139145    removeRestriction(MediaSession::Audio, MetadataPreloadingNotPermitted);
    140146    removeRestriction(MediaSession::Video, MetadataPreloadingNotPermitted);
     147
    141148    addRestriction(MediaSession::Audio, AutoPreloadingNotPermitted);
    142149    addRestriction(MediaSession::Video, AutoPreloadingNotPermitted);
     
    194201   
    195202    double currentTime = currentSession->currentTime();
    196     if (std::isfinite(currentTime))
     203    if (std::isfinite(currentTime) && currentTime != MediaPlayer::invalidTime())
    197204        [info setValue:@(currentTime) forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
    198205   
  • trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.cpp

    r163657 r167767  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4747    if (has(MediaSession::WebAudio))
    4848        AudioSession::sharedSession().setPreferredBufferSize(kWebAudioBufferSize);
    49     // FIXME: <http://webkit.org/b/116725> Figure out why enabling the code below
    50     // causes media LayoutTests to fail on 10.8.
    5149#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
    52     else if ((has(MediaSession::Video) || has(MediaSession::Audio)) && Settings::lowPowerVideoAudioBufferSizeEnabled())
     50    else if ((has(MediaSession::Video) || has(MediaSession::Audio)) && Settings::lowPowerVideoAudioBufferSizeEnabled()) {
     51        // FIXME: <http://webkit.org/b/116725> Figure out why enabling the code below
     52        // causes media LayoutTests to fail on 10.8.
    5353        AudioSession::sharedSession().setPreferredBufferSize(kLowPowerVideoBufferSize);
     54    }
     55#endif
     56
     57#if PLATFORM(IOS)
     58    if (has(MediaSession::WebAudio))
     59        AudioSession::sharedSession().setActive(true);
     60    else
     61        AudioSession::sharedSession().setActive(false);
     62
     63    if (!Settings::shouldManageAudioSession())
     64        return;
     65
     66    if (has(MediaSession::Video) || has(MediaSession::Audio))
     67        AudioSession::sharedSession().setCategory(AudioSession::MediaPlayback);
     68    else if (has(MediaSession::WebAudio))
     69        AudioSession::sharedSession().setCategory(AudioSession::AmbientSound);
    5470#endif
    5571}
  • trunk/Source/WebKit/mac/ChangeLog

    r167745 r167767  
     12014-04-24  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [iOS] Manage AudioSession category according to media type
     4        https://bugs.webkit.org/show_bug.cgi?id=132096
     5
     6        Reviewed by Jer Noble.
     7
     8        * WebView/WebView.mm:
     9        (-[WebView _commonInitializationWithFrameName:groupName:]): Tell
     10            WebCore to manage the AudioSession when running in MobileSafari.
     11
    1122014-04-23  Andreas Kling  <akling@apple.com>
    213
  • trunk/Source/WebKit/mac/WebView/WebView.mm

    r167730 r167767  
    903903        Settings::setShouldRespectPriorityInCSSAttributeSetters(shouldRespectPriorityInCSSAttributeSetters());
    904904
     905#if PLATFORM(IOS)
     906        if (applicationIsMobileSafari())
     907            Settings::setShouldManageAudioSession(true);
     908#endif
     909
    905910        didOneTimeInitialization = true;
    906911    }
  • trunk/Source/WebKit2/ChangeLog

    r167766 r167767  
     12014-04-24  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [iOS] Manage AudioSession category according to media type
     4        https://bugs.webkit.org/show_bug.cgi?id=132096
     5
     6        Reviewed by Jer Noble.
     7
     8        * WebProcess/WebPage/WebPage.cpp:
     9        (WebKit::WebPage::WebPage): Tell WebCore to manage the AudioSession.
     10
    1112014-04-24  Tim Horton  <timothy_horton@apple.com>
    212
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r167742 r167767  
    311311    Settings::setDefaultMinDOMTimerInterval(0.004);
    312312
     313#if PLATFORM(IOS)
     314    Settings::setShouldManageAudioSession(true);
     315#endif
     316
    313317    Page::PageClients pageClients;
    314318    pageClients.chromeClient = new WebChromeClient(this);
Note: See TracChangeset for help on using the changeset viewer.