Chromium Code Reviews| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 m_closedContextSampleRate(-1), | 100 m_closedContextSampleRate(-1), |
| 101 m_periodicWaveSine(nullptr), | 101 m_periodicWaveSine(nullptr), |
| 102 m_periodicWaveSquare(nullptr), | 102 m_periodicWaveSquare(nullptr), |
| 103 m_periodicWaveSawtooth(nullptr), | 103 m_periodicWaveSawtooth(nullptr), |
| 104 m_periodicWaveTriangle(nullptr) { | 104 m_periodicWaveTriangle(nullptr) { |
| 105 // If mediaPlaybackRequiresUserGesture is enabled, cross origin iframes will | 105 // If mediaPlaybackRequiresUserGesture is enabled, cross origin iframes will |
| 106 // require user gesture for the AudioContext to produce sound. | 106 // require user gesture for the AudioContext to produce sound. |
| 107 if (document->settings() && | 107 if (document->settings() && |
| 108 document->settings()->mediaPlaybackRequiresUserGesture() && | 108 document->settings()->mediaPlaybackRequiresUserGesture() && |
| 109 document->frame() && document->frame()->isCrossOriginSubframe()) { | 109 document->frame() && document->frame()->isCrossOriginSubframe()) { |
| 110 m_autoplayStatus = AutoplayStatus::AutoplayStatusFailed; | |
| 110 m_userGestureRequired = true; | 111 m_userGestureRequired = true; |
| 111 } | 112 } |
| 112 | 113 |
| 113 m_destinationNode = DefaultAudioDestinationNode::create(this); | 114 m_destinationNode = DefaultAudioDestinationNode::create(this); |
| 114 | 115 |
| 115 initialize(); | 116 initialize(); |
| 116 } | 117 } |
| 117 | 118 |
| 118 // Constructor for offline (non-realtime) rendering. | 119 // Constructor for offline (non-realtime) rendering. |
| 119 BaseAudioContext::BaseAudioContext(Document* document, | 120 BaseAudioContext::BaseAudioContext(Document* document, |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 137 | 138 |
| 138 BaseAudioContext::~BaseAudioContext() { | 139 BaseAudioContext::~BaseAudioContext() { |
| 139 deferredTaskHandler().contextWillBeDestroyed(); | 140 deferredTaskHandler().contextWillBeDestroyed(); |
| 140 // AudioNodes keep a reference to their context, so there should be no way to | 141 // AudioNodes keep a reference to their context, so there should be no way to |
| 141 // be in the destructor if there are still AudioNodes around. | 142 // be in the destructor if there are still AudioNodes around. |
| 142 DCHECK(!isDestinationInitialized()); | 143 DCHECK(!isDestinationInitialized()); |
| 143 DCHECK(!m_activeSourceNodes.size()); | 144 DCHECK(!m_activeSourceNodes.size()); |
| 144 DCHECK(!m_finishedSourceHandlers.size()); | 145 DCHECK(!m_finishedSourceHandlers.size()); |
| 145 DCHECK(!m_isResolvingResumePromises); | 146 DCHECK(!m_isResolvingResumePromises); |
| 146 DCHECK(!m_resumeResolvers.size()); | 147 DCHECK(!m_resumeResolvers.size()); |
| 148 | |
| 149 recordAutoplayStatus(); | |
|
Raymond Toy
2016/10/10 17:05:10
I think if the user closes a tab, everything goes
mlamouri (slow - plz ping)
2016/10/10 18:44:40
I guess if the object is marked as GCFinalized, it
| |
| 147 } | 150 } |
| 148 | 151 |
| 149 void BaseAudioContext::initialize() { | 152 void BaseAudioContext::initialize() { |
| 150 if (isDestinationInitialized()) | 153 if (isDestinationInitialized()) |
| 151 return; | 154 return; |
| 152 | 155 |
| 153 FFTFrame::initialize(); | 156 FFTFrame::initialize(); |
| 154 | 157 |
| 155 if (m_destinationNode) { | 158 if (m_destinationNode) { |
| 156 m_destinationNode->handler().initialize(); | 159 m_destinationNode->handler().initialize(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 m_listener->waitForHRTFDatabaseLoaderThreadCompletion(); | 192 m_listener->waitForHRTFDatabaseLoaderThreadCompletion(); |
| 190 | 193 |
| 191 clear(); | 194 clear(); |
| 192 } | 195 } |
| 193 | 196 |
| 194 void BaseAudioContext::contextDestroyed() { | 197 void BaseAudioContext::contextDestroyed() { |
| 195 uninitialize(); | 198 uninitialize(); |
| 196 } | 199 } |
| 197 | 200 |
| 198 bool BaseAudioContext::hasPendingActivity() const { | 201 bool BaseAudioContext::hasPendingActivity() const { |
| 202 LOG(INFO) << "hasPendingActivity() => " << !m_isCleared; | |
|
Raymond Toy
2016/10/10 17:05:10
Do you really want this log? Just asking.
mlamouri (slow - plz ping)
2016/10/10 18:44:40
No :)
| |
| 199 // There's no pending activity if the audio context has been cleared. | 203 // There's no pending activity if the audio context has been cleared. |
| 200 return !m_isCleared; | 204 return !m_isCleared; |
| 201 } | 205 } |
| 202 | 206 |
| 203 AudioDestinationNode* BaseAudioContext::destination() const { | 207 AudioDestinationNode* BaseAudioContext::destination() const { |
| 204 // Cannot be called from the audio thread because this method touches objects | 208 // Cannot be called from the audio thread because this method touches objects |
| 205 // managed by Oilpan, and the audio thread is not managed by Oilpan. | 209 // managed by Oilpan, and the audio thread is not managed by Oilpan. |
| 206 DCHECK(!isAudioThread()); | 210 DCHECK(!isAudioThread()); |
| 207 return m_destinationNode; | 211 return m_destinationNode; |
| 208 } | 212 } |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 546 // Initialize the table if necessary | 550 // Initialize the table if necessary |
| 547 if (!m_periodicWaveTriangle) | 551 if (!m_periodicWaveTriangle) |
| 548 m_periodicWaveTriangle = PeriodicWave::createTriangle(sampleRate()); | 552 m_periodicWaveTriangle = PeriodicWave::createTriangle(sampleRate()); |
| 549 return m_periodicWaveTriangle; | 553 return m_periodicWaveTriangle; |
| 550 default: | 554 default: |
| 551 NOTREACHED(); | 555 NOTREACHED(); |
| 552 return nullptr; | 556 return nullptr; |
| 553 } | 557 } |
| 554 } | 558 } |
| 555 | 559 |
| 560 void BaseAudioContext::maybeRecordStartAttempt() { | |
| 561 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture()) | |
| 562 return; | |
| 563 | |
| 564 DCHECK(!m_autoplayStatus.has_value() || | |
| 565 m_autoplayStatus != AutoplayStatus::AutoplayStatusSucceeded); | |
| 566 m_autoplayStatus = AutoplayStatus::AutoplayStatusFailedWithStart; | |
| 567 } | |
| 568 | |
| 556 String BaseAudioContext::state() const { | 569 String BaseAudioContext::state() const { |
| 557 // These strings had better match the strings for AudioContextState in | 570 // These strings had better match the strings for AudioContextState in |
| 558 // AudioContext.idl. | 571 // AudioContext.idl. |
| 559 switch (m_contextState) { | 572 switch (m_contextState) { |
| 560 case Suspended: | 573 case Suspended: |
| 561 return "suspended"; | 574 return "suspended"; |
| 562 case Running: | 575 case Running: |
| 563 return "running"; | 576 return "running"; |
| 564 case Closed: | 577 case Closed: |
| 565 return "closed"; | 578 return "closed"; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 768 for (auto& resolver : m_decodeAudioResolvers) | 781 for (auto& resolver : m_decodeAudioResolvers) |
| 769 resolver->reject( | 782 resolver->reject( |
| 770 DOMException::create(InvalidStateError, "Audio context is going away")); | 783 DOMException::create(InvalidStateError, "Audio context is going away")); |
| 771 m_decodeAudioResolvers.clear(); | 784 m_decodeAudioResolvers.clear(); |
| 772 } | 785 } |
| 773 | 786 |
| 774 void BaseAudioContext::maybeUnlockUserGesture() { | 787 void BaseAudioContext::maybeUnlockUserGesture() { |
| 775 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture()) | 788 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture()) |
| 776 return; | 789 return; |
| 777 | 790 |
| 791 DCHECK(!m_autoplayStatus.has_value() || | |
| 792 m_autoplayStatus != AutoplayStatus::AutoplayStatusSucceeded); | |
| 793 | |
| 778 UserGestureIndicator::utilizeUserGesture(); | 794 UserGestureIndicator::utilizeUserGesture(); |
| 779 m_userGestureRequired = false; | 795 m_userGestureRequired = false; |
| 796 m_autoplayStatus = AutoplayStatus::AutoplayStatusSucceeded; | |
| 780 } | 797 } |
| 781 | 798 |
| 782 bool BaseAudioContext::isAllowedToStart() const { | 799 bool BaseAudioContext::isAllowedToStart() const { |
| 783 if (!m_userGestureRequired) | 800 if (!m_userGestureRequired) |
| 784 return true; | 801 return true; |
| 785 | 802 |
| 786 toDocument(getExecutionContext()) | 803 toDocument(getExecutionContext()) |
| 787 ->addConsoleMessage(ConsoleMessage::create( | 804 ->addConsoleMessage(ConsoleMessage::create( |
| 788 JSMessageSource, WarningMessageLevel, | 805 JSMessageSource, WarningMessageLevel, |
| 789 "An AudioContext in a cross origin iframe must be created or resumed " | 806 "An AudioContext in a cross origin iframe must be created or resumed " |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 800 for (auto& resolver : m_resumeResolvers) { | 817 for (auto& resolver : m_resumeResolvers) { |
| 801 resolver->reject( | 818 resolver->reject( |
| 802 DOMException::create(InvalidStateError, "Audio context is going away")); | 819 DOMException::create(InvalidStateError, "Audio context is going away")); |
| 803 } | 820 } |
| 804 m_resumeResolvers.clear(); | 821 m_resumeResolvers.clear(); |
| 805 m_isResolvingResumePromises = false; | 822 m_isResolvingResumePromises = false; |
| 806 | 823 |
| 807 rejectPendingDecodeAudioDataResolvers(); | 824 rejectPendingDecodeAudioDataResolvers(); |
| 808 } | 825 } |
| 809 | 826 |
| 827 void BaseAudioContext::recordAutoplayStatus() { | |
| 828 if (!m_autoplayStatus.has_value()) | |
| 829 return; | |
| 830 | |
| 831 DEFINE_STATIC_LOCAL( | |
| 832 EnumerationHistogram, autoplayHistogram, | |
| 833 ("WebAudio.Autoplay.CrossOrigin", AutoplayStatus::AutoplayStatusCount)); | |
| 834 autoplayHistogram.count(m_autoplayStatus.value()); | |
| 835 | |
| 836 m_autoplayStatus.reset(); | |
| 837 } | |
| 838 | |
| 810 const AtomicString& BaseAudioContext::interfaceName() const { | 839 const AtomicString& BaseAudioContext::interfaceName() const { |
| 811 return EventTargetNames::AudioContext; | 840 return EventTargetNames::AudioContext; |
| 812 } | 841 } |
| 813 | 842 |
| 814 ExecutionContext* BaseAudioContext::getExecutionContext() const { | 843 ExecutionContext* BaseAudioContext::getExecutionContext() const { |
| 815 return ActiveDOMObject::getExecutionContext(); | 844 return ActiveDOMObject::getExecutionContext(); |
| 816 } | 845 } |
| 817 | 846 |
| 818 void BaseAudioContext::startRendering() { | 847 void BaseAudioContext::startRendering() { |
| 819 // This is called for both online and offline contexts. | 848 // This is called for both online and offline contexts. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 843 } | 872 } |
| 844 | 873 |
| 845 SecurityOrigin* BaseAudioContext::getSecurityOrigin() const { | 874 SecurityOrigin* BaseAudioContext::getSecurityOrigin() const { |
| 846 if (getExecutionContext()) | 875 if (getExecutionContext()) |
| 847 return getExecutionContext()->getSecurityOrigin(); | 876 return getExecutionContext()->getSecurityOrigin(); |
| 848 | 877 |
| 849 return nullptr; | 878 return nullptr; |
| 850 } | 879 } |
| 851 | 880 |
| 852 } // namespace blink | 881 } // namespace blink |
| OLD | NEW |