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

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: fix 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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();
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 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 // Initialize the table if necessary 549 // Initialize the table if necessary
547 if (!m_periodicWaveTriangle) 550 if (!m_periodicWaveTriangle)
548 m_periodicWaveTriangle = PeriodicWave::createTriangle(sampleRate()); 551 m_periodicWaveTriangle = PeriodicWave::createTriangle(sampleRate());
549 return m_periodicWaveTriangle; 552 return m_periodicWaveTriangle;
550 default: 553 default:
551 NOTREACHED(); 554 NOTREACHED();
552 return nullptr; 555 return nullptr;
553 } 556 }
554 } 557 }
555 558
559 void BaseAudioContext::maybeRecordStartAttempt() {
560 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture())
561 return;
562
563 DCHECK(!m_autoplayStatus.has_value() ||
564 m_autoplayStatus != AutoplayStatus::AutoplayStatusSucceeded);
565 m_autoplayStatus = AutoplayStatus::AutoplayStatusFailedWithStart;
566 }
567
556 String BaseAudioContext::state() const { 568 String BaseAudioContext::state() const {
557 // These strings had better match the strings for AudioContextState in 569 // These strings had better match the strings for AudioContextState in
558 // AudioContext.idl. 570 // AudioContext.idl.
559 switch (m_contextState) { 571 switch (m_contextState) {
560 case Suspended: 572 case Suspended:
561 return "suspended"; 573 return "suspended";
562 case Running: 574 case Running:
563 return "running"; 575 return "running";
564 case Closed: 576 case Closed:
565 return "closed"; 577 return "closed";
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 for (auto& resolver : m_decodeAudioResolvers) 780 for (auto& resolver : m_decodeAudioResolvers)
769 resolver->reject( 781 resolver->reject(
770 DOMException::create(InvalidStateError, "Audio context is going away")); 782 DOMException::create(InvalidStateError, "Audio context is going away"));
771 m_decodeAudioResolvers.clear(); 783 m_decodeAudioResolvers.clear();
772 } 784 }
773 785
774 void BaseAudioContext::maybeUnlockUserGesture() { 786 void BaseAudioContext::maybeUnlockUserGesture() {
775 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture()) 787 if (!m_userGestureRequired || !UserGestureIndicator::processingUserGesture())
776 return; 788 return;
777 789
790 DCHECK(!m_autoplayStatus.has_value() ||
791 m_autoplayStatus != AutoplayStatus::AutoplayStatusSucceeded);
792
778 UserGestureIndicator::utilizeUserGesture(); 793 UserGestureIndicator::utilizeUserGesture();
779 m_userGestureRequired = false; 794 m_userGestureRequired = false;
795 m_autoplayStatus = AutoplayStatus::AutoplayStatusSucceeded;
780 } 796 }
781 797
782 bool BaseAudioContext::isAllowedToStart() const { 798 bool BaseAudioContext::isAllowedToStart() const {
783 if (!m_userGestureRequired) 799 if (!m_userGestureRequired)
784 return true; 800 return true;
785 801
786 toDocument(getExecutionContext()) 802 toDocument(getExecutionContext())
787 ->addConsoleMessage(ConsoleMessage::create( 803 ->addConsoleMessage(ConsoleMessage::create(
788 JSMessageSource, WarningMessageLevel, 804 JSMessageSource, WarningMessageLevel,
789 "An AudioContext in a cross origin iframe must be created or resumed " 805 "An AudioContext in a cross origin iframe must be created or resumed "
(...skipping 10 matching lines...) Expand all
800 for (auto& resolver : m_resumeResolvers) { 816 for (auto& resolver : m_resumeResolvers) {
801 resolver->reject( 817 resolver->reject(
802 DOMException::create(InvalidStateError, "Audio context is going away")); 818 DOMException::create(InvalidStateError, "Audio context is going away"));
803 } 819 }
804 m_resumeResolvers.clear(); 820 m_resumeResolvers.clear();
805 m_isResolvingResumePromises = false; 821 m_isResolvingResumePromises = false;
806 822
807 rejectPendingDecodeAudioDataResolvers(); 823 rejectPendingDecodeAudioDataResolvers();
808 } 824 }
809 825
826 void BaseAudioContext::recordAutoplayStatus() {
827 if (!m_autoplayStatus.has_value())
828 return;
829
830 DEFINE_STATIC_LOCAL(
831 EnumerationHistogram, autoplayHistogram,
832 ("WebAudio.Autoplay.CrossOrigin", AutoplayStatus::AutoplayStatusCount));
833 autoplayHistogram.count(m_autoplayStatus.value());
834
835 m_autoplayStatus.reset();
836 }
837
810 const AtomicString& BaseAudioContext::interfaceName() const { 838 const AtomicString& BaseAudioContext::interfaceName() const {
811 return EventTargetNames::AudioContext; 839 return EventTargetNames::AudioContext;
812 } 840 }
813 841
814 ExecutionContext* BaseAudioContext::getExecutionContext() const { 842 ExecutionContext* BaseAudioContext::getExecutionContext() const {
815 return ActiveDOMObject::getExecutionContext(); 843 return ActiveDOMObject::getExecutionContext();
816 } 844 }
817 845
818 void BaseAudioContext::startRendering() { 846 void BaseAudioContext::startRendering() {
819 // This is called for both online and offline contexts. 847 // This is called for both online and offline contexts.
(...skipping 23 matching lines...) Expand all
843 } 871 }
844 872
845 SecurityOrigin* BaseAudioContext::getSecurityOrigin() const { 873 SecurityOrigin* BaseAudioContext::getSecurityOrigin() const {
846 if (getExecutionContext()) 874 if (getExecutionContext())
847 return getExecutionContext()->getSecurityOrigin(); 875 return getExecutionContext()->getSecurityOrigin();
848 876
849 return nullptr; 877 return nullptr;
850 } 878 }
851 879
852 } // namespace blink 880 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698