| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010, Google Inc. All rights reserved. | 2 * Copyright (C) 2010, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 m_closedContextSampleRate(-1), | 101 m_closedContextSampleRate(-1), |
| 102 m_periodicWaveSine(nullptr), | 102 m_periodicWaveSine(nullptr), |
| 103 m_periodicWaveSquare(nullptr), | 103 m_periodicWaveSquare(nullptr), |
| 104 m_periodicWaveSawtooth(nullptr), | 104 m_periodicWaveSawtooth(nullptr), |
| 105 m_periodicWaveTriangle(nullptr) { | 105 m_periodicWaveTriangle(nullptr) { |
| 106 // If mediaPlaybackRequiresUserGesture is enabled, cross origin iframes will | 106 // If mediaPlaybackRequiresUserGesture is enabled, cross origin iframes will |
| 107 // require user gesture for the AudioContext to produce sound. | 107 // require user gesture for the AudioContext to produce sound. |
| 108 if (document->settings() && | 108 if (document->settings() && |
| 109 document->settings()->mediaPlaybackRequiresUserGesture() && | 109 document->settings()->mediaPlaybackRequiresUserGesture() && |
| 110 document->frame() && document->frame()->isCrossOriginSubframe()) { | 110 document->frame() && document->frame()->isCrossOriginSubframe()) { |
| 111 m_autoplayStatus = AutoplayStatus::AutoplayStatusFailed; |
| 111 m_userGestureRequired = true; | 112 m_userGestureRequired = true; |
| 112 } | 113 } |
| 113 | 114 |
| 114 m_destinationNode = DefaultAudioDestinationNode::create(this); | 115 m_destinationNode = DefaultAudioDestinationNode::create(this); |
| 115 | 116 |
| 116 initialize(); | 117 initialize(); |
| 117 } | 118 } |
| 118 | 119 |
| 119 // Constructor for offline (non-realtime) rendering. | 120 // Constructor for offline (non-realtime) rendering. |
| 120 BaseAudioContext::BaseAudioContext(Document* document, | 121 BaseAudioContext::BaseAudioContext(Document* document, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 138 | 139 |
| 139 BaseAudioContext::~BaseAudioContext() { | 140 BaseAudioContext::~BaseAudioContext() { |
| 140 deferredTaskHandler().contextWillBeDestroyed(); | 141 deferredTaskHandler().contextWillBeDestroyed(); |
| 141 // AudioNodes keep a reference to their context, so there should be no way to | 142 // AudioNodes keep a reference to their context, so there should be no way to |
| 142 // be in the destructor if there are still AudioNodes around. | 143 // be in the destructor if there are still AudioNodes around. |
| 143 DCHECK(!isDestinationInitialized()); | 144 DCHECK(!isDestinationInitialized()); |
| 144 DCHECK(!m_activeSourceNodes.size()); | 145 DCHECK(!m_activeSourceNodes.size()); |
| 145 DCHECK(!m_finishedSourceHandlers.size()); | 146 DCHECK(!m_finishedSourceHandlers.size()); |
| 146 DCHECK(!m_isResolvingResumePromises); | 147 DCHECK(!m_isResolvingResumePromises); |
| 147 DCHECK(!m_resumeResolvers.size()); | 148 DCHECK(!m_resumeResolvers.size()); |
| 149 DCHECK(!m_autoplayStatus.has_value()); |
| 148 } | 150 } |
| 149 | 151 |
| 150 void BaseAudioContext::initialize() { | 152 void BaseAudioContext::initialize() { |
| 151 if (isDestinationInitialized()) | 153 if (isDestinationInitialized()) |
| 152 return; | 154 return; |
| 153 | 155 |
| 154 FFTFrame::initialize(); | 156 FFTFrame::initialize(); |
| 155 | 157 |
| 156 if (m_destinationNode) { | 158 if (m_destinationNode) { |
| 157 m_destinationNode->handler().initialize(); | 159 m_destinationNode->handler().initialize(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 182 // Get rid of the sources which may still be playing. | 184 // Get rid of the sources which may still be playing. |
| 183 releaseActiveSourceNodes(); | 185 releaseActiveSourceNodes(); |
| 184 | 186 |
| 185 // Reject any pending resolvers before we go away. | 187 // Reject any pending resolvers before we go away. |
| 186 rejectPendingResolvers(); | 188 rejectPendingResolvers(); |
| 187 didClose(); | 189 didClose(); |
| 188 | 190 |
| 189 DCHECK(m_listener); | 191 DCHECK(m_listener); |
| 190 m_listener->waitForHRTFDatabaseLoaderThreadCompletion(); | 192 m_listener->waitForHRTFDatabaseLoaderThreadCompletion(); |
| 191 | 193 |
| 194 recordAutoplayStatus(); |
| 195 |
| 192 clear(); | 196 clear(); |
| 193 } | 197 } |
| 194 | 198 |
| 195 void BaseAudioContext::contextDestroyed() { | 199 void BaseAudioContext::contextDestroyed() { |
| 196 uninitialize(); | 200 uninitialize(); |
| 197 } | 201 } |
| 198 | 202 |
| 199 bool BaseAudioContext::hasPendingActivity() const { | 203 bool BaseAudioContext::hasPendingActivity() const { |
| 200 // There's no pending activity if the audio context has been cleared. | 204 // There's no pending activity if the audio context has been cleared. |
| 201 return !m_isCleared; | 205 return !m_isCleared; |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 // Initialize the table if necessary | 559 // Initialize the table if necessary |
| 556 if (!m_periodicWaveTriangle) | 560 if (!m_periodicWaveTriangle) |
| 557 m_periodicWaveTriangle = PeriodicWave::createTriangle(sampleRate()); | 561 m_periodicWaveTriangle = PeriodicWave::createTriangle(sampleRate()); |
| 558 return m_periodicWaveTriangle; | 562 return m_periodicWaveTriangle; |
| 559 default: | 563 default: |
| 560 NOTREACHED(); | 564 NOTREACHED(); |
| 561 return nullptr; | 565 return nullptr; |
| 562 } | 566 } |
| 563 } | 567 } |
| 564 | 568 |
| 569 void BaseAudioContext::maybeRecordStartAttempt() { |
| 570 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture()) |
| 571 return; |
| 572 |
| 573 DCHECK(!m_autoplayStatus.has_value() || |
| 574 m_autoplayStatus != AutoplayStatus::AutoplayStatusSucceeded); |
| 575 m_autoplayStatus = AutoplayStatus::AutoplayStatusFailedWithStart; |
| 576 } |
| 577 |
| 565 String BaseAudioContext::state() const { | 578 String BaseAudioContext::state() const { |
| 566 // These strings had better match the strings for AudioContextState in | 579 // These strings had better match the strings for AudioContextState in |
| 567 // AudioContext.idl. | 580 // AudioContext.idl. |
| 568 switch (m_contextState) { | 581 switch (m_contextState) { |
| 569 case Suspended: | 582 case Suspended: |
| 570 return "suspended"; | 583 return "suspended"; |
| 571 case Running: | 584 case Running: |
| 572 return "running"; | 585 return "running"; |
| 573 case Closed: | 586 case Closed: |
| 574 return "closed"; | 587 return "closed"; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 for (auto& resolver : m_decodeAudioResolvers) | 790 for (auto& resolver : m_decodeAudioResolvers) |
| 778 resolver->reject( | 791 resolver->reject( |
| 779 DOMException::create(InvalidStateError, "Audio context is going away")); | 792 DOMException::create(InvalidStateError, "Audio context is going away")); |
| 780 m_decodeAudioResolvers.clear(); | 793 m_decodeAudioResolvers.clear(); |
| 781 } | 794 } |
| 782 | 795 |
| 783 void BaseAudioContext::maybeUnlockUserGesture() { | 796 void BaseAudioContext::maybeUnlockUserGesture() { |
| 784 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture()) | 797 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture()) |
| 785 return; | 798 return; |
| 786 | 799 |
| 800 DCHECK(!m_autoplayStatus.has_value() || |
| 801 m_autoplayStatus != AutoplayStatus::AutoplayStatusSucceeded); |
| 802 |
| 787 UserGestureIndicator::utilizeUserGesture(); | 803 UserGestureIndicator::utilizeUserGesture(); |
| 788 m_userGestureRequired = false; | 804 m_userGestureRequired = false; |
| 805 m_autoplayStatus = AutoplayStatus::AutoplayStatusSucceeded; |
| 789 } | 806 } |
| 790 | 807 |
| 791 bool BaseAudioContext::isAllowedToStart() const { | 808 bool BaseAudioContext::isAllowedToStart() const { |
| 792 if (!m_userGestureRequired) | 809 if (!m_userGestureRequired) |
| 793 return true; | 810 return true; |
| 794 | 811 |
| 795 toDocument(getExecutionContext()) | 812 toDocument(getExecutionContext()) |
| 796 ->addConsoleMessage(ConsoleMessage::create( | 813 ->addConsoleMessage(ConsoleMessage::create( |
| 797 JSMessageSource, WarningMessageLevel, | 814 JSMessageSource, WarningMessageLevel, |
| 798 "An AudioContext in a cross origin iframe must be created or resumed " | 815 "An AudioContext in a cross origin iframe must be created or resumed " |
| (...skipping 10 matching lines...) Expand all Loading... |
| 809 for (auto& resolver : m_resumeResolvers) { | 826 for (auto& resolver : m_resumeResolvers) { |
| 810 resolver->reject( | 827 resolver->reject( |
| 811 DOMException::create(InvalidStateError, "Audio context is going away")); | 828 DOMException::create(InvalidStateError, "Audio context is going away")); |
| 812 } | 829 } |
| 813 m_resumeResolvers.clear(); | 830 m_resumeResolvers.clear(); |
| 814 m_isResolvingResumePromises = false; | 831 m_isResolvingResumePromises = false; |
| 815 | 832 |
| 816 rejectPendingDecodeAudioDataResolvers(); | 833 rejectPendingDecodeAudioDataResolvers(); |
| 817 } | 834 } |
| 818 | 835 |
| 836 void BaseAudioContext::recordAutoplayStatus() { |
| 837 if (!m_autoplayStatus.has_value()) |
| 838 return; |
| 839 |
| 840 DEFINE_STATIC_LOCAL( |
| 841 EnumerationHistogram, autoplayHistogram, |
| 842 ("WebAudio.Autoplay.CrossOrigin", AutoplayStatus::AutoplayStatusCount)); |
| 843 autoplayHistogram.count(m_autoplayStatus.value()); |
| 844 |
| 845 m_autoplayStatus.reset(); |
| 846 } |
| 847 |
| 819 const AtomicString& BaseAudioContext::interfaceName() const { | 848 const AtomicString& BaseAudioContext::interfaceName() const { |
| 820 return EventTargetNames::AudioContext; | 849 return EventTargetNames::AudioContext; |
| 821 } | 850 } |
| 822 | 851 |
| 823 ExecutionContext* BaseAudioContext::getExecutionContext() const { | 852 ExecutionContext* BaseAudioContext::getExecutionContext() const { |
| 824 return ActiveDOMObject::getExecutionContext(); | 853 return ActiveDOMObject::getExecutionContext(); |
| 825 } | 854 } |
| 826 | 855 |
| 827 void BaseAudioContext::startRendering() { | 856 void BaseAudioContext::startRendering() { |
| 828 // This is called for both online and offline contexts. | 857 // This is called for both online and offline contexts. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 852 } | 881 } |
| 853 | 882 |
| 854 SecurityOrigin* BaseAudioContext::getSecurityOrigin() const { | 883 SecurityOrigin* BaseAudioContext::getSecurityOrigin() const { |
| 855 if (getExecutionContext()) | 884 if (getExecutionContext()) |
| 856 return getExecutionContext()->getSecurityOrigin(); | 885 return getExecutionContext()->getSecurityOrigin(); |
| 857 | 886 |
| 858 return nullptr; | 887 return nullptr; |
| 859 } | 888 } |
| 860 | 889 |
| 861 } // namespace blink | 890 } // namespace blink |
| OLD | NEW |