Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp

Issue 2404743002: Web Audio: record autoplay status when an AudioContext is destroyed. (Closed)
Patch Set: move recording Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698