Commit 07772742 authored by andresp@chromium.org's avatar andresp@chromium.org

Add histogram WebRTC.UserMediaRequest.NoResultState to track user media requests with no result.

BUG=399835

Review URL: https://codereview.chromium.org/446553002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287862 0039d316-1c4b-4281-b951-d872f2087c98
parent 9e9bef02
...@@ -199,6 +199,7 @@ void MediaStreamImpl::cancelUserMediaRequest( ...@@ -199,6 +199,7 @@ void MediaStreamImpl::cancelUserMediaRequest(
// We can't abort the stream generation process. // We can't abort the stream generation process.
// Instead, erase the request. Once the stream is generated we will stop the // Instead, erase the request. Once the stream is generated we will stop the
// stream if the request does not exist. // stream if the request does not exist.
LogUserMediaRequestWithNoResult(MEDIA_STREAM_REQUEST_EXPLICITLY_CANCELLED);
DeleteUserMediaRequestInfo(request); DeleteUserMediaRequestInfo(request);
} }
} }
...@@ -275,20 +276,8 @@ void MediaStreamImpl::OnStreamGenerated( ...@@ -275,20 +276,8 @@ void MediaStreamImpl::OnStreamGenerated(
if (!request_info) { if (!request_info) {
// This can happen if the request is canceled or the frame reloads while // This can happen if the request is canceled or the frame reloads while
// MediaStreamDispatcher is processing the request. // MediaStreamDispatcher is processing the request.
// Only stop the device if the device is not used in another MediaStream.
for (StreamDeviceInfoArray::const_iterator device_it = audio_array.begin();
device_it != audio_array.end(); ++device_it) {
if (!FindLocalSource(*device_it))
media_stream_dispatcher_->StopStreamDevice(*device_it);
}
for (StreamDeviceInfoArray::const_iterator device_it = video_array.begin();
device_it != video_array.end(); ++device_it) {
if (!FindLocalSource(*device_it))
media_stream_dispatcher_->StopStreamDevice(*device_it);
}
DVLOG(1) << "Request ID not found"; DVLOG(1) << "Request ID not found";
OnStreamGeneratedForCancelledRequest(audio_array, video_array);
return; return;
} }
request_info->generated = true; request_info->generated = true;
...@@ -332,6 +321,23 @@ void MediaStreamImpl::OnStreamGenerated( ...@@ -332,6 +321,23 @@ void MediaStreamImpl::OnStreamGenerated(
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
} }
void MediaStreamImpl::OnStreamGeneratedForCancelledRequest(
const StreamDeviceInfoArray& audio_array,
const StreamDeviceInfoArray& video_array) {
// Only stop the device if the device is not used in another MediaStream.
for (StreamDeviceInfoArray::const_iterator device_it = audio_array.begin();
device_it != audio_array.end(); ++device_it) {
if (!FindLocalSource(*device_it))
media_stream_dispatcher_->StopStreamDevice(*device_it);
}
for (StreamDeviceInfoArray::const_iterator device_it = video_array.begin();
device_it != video_array.end(); ++device_it) {
if (!FindLocalSource(*device_it))
media_stream_dispatcher_->StopStreamDevice(*device_it);
}
}
// Callback from MediaStreamDispatcher. // Callback from MediaStreamDispatcher.
// The requested stream failed to be generated. // The requested stream failed to be generated.
void MediaStreamImpl::OnStreamGenerationFailed( void MediaStreamImpl::OnStreamGenerationFailed(
...@@ -701,6 +707,29 @@ void MediaStreamImpl::DeleteUserMediaRequestInfo( ...@@ -701,6 +707,29 @@ void MediaStreamImpl::DeleteUserMediaRequestInfo(
NOTREACHED(); NOTREACHED();
} }
void MediaStreamImpl::DeleteAllUserMediaRequests() {
UserMediaRequests::iterator request_it = user_media_requests_.begin();
while (request_it != user_media_requests_.end()) {
DVLOG(1) << "MediaStreamImpl@" << this << "::DeleteAllUserMediaRequests: "
<< "Cancel user media request " << (*request_it)->request_id;
// If the request is not generated, it means that a request
// has been sent to the MediaStreamDispatcher to generate a stream
// but MediaStreamDispatcher has not yet responded and we need to cancel
// the request.
if (!(*request_it)->generated) {
DCHECK(!(*request_it)->HasPendingSources());
media_stream_dispatcher_->CancelGenerateStream(
(*request_it)->request_id, weak_factory_.GetWeakPtr());
LogUserMediaRequestWithNoResult(MEDIA_STREAM_REQUEST_NOT_GENERATED);
} else {
DCHECK((*request_it)->HasPendingSources());
LogUserMediaRequestWithNoResult(
MEDIA_STREAM_REQUEST_PENDING_MEDIA_TRACKS);
}
request_it = user_media_requests_.erase(request_it);
}
}
MediaStreamImpl::MediaDevicesRequestInfo* MediaStreamImpl::MediaDevicesRequestInfo*
MediaStreamImpl::FindMediaDevicesRequestInfo( MediaStreamImpl::FindMediaDevicesRequestInfo(
int request_id) { int request_id) {
...@@ -748,20 +777,7 @@ void MediaStreamImpl::CancelAndDeleteMediaDevicesRequest( ...@@ -748,20 +777,7 @@ void MediaStreamImpl::CancelAndDeleteMediaDevicesRequest(
void MediaStreamImpl::FrameWillClose() { void MediaStreamImpl::FrameWillClose() {
// Cancel all outstanding UserMediaRequests. // Cancel all outstanding UserMediaRequests.
UserMediaRequests::iterator request_it = user_media_requests_.begin(); DeleteAllUserMediaRequests();
while (request_it != user_media_requests_.end()) {
DVLOG(1) << "MediaStreamImpl@" << this << "::FrameWillClose: "
<< "Cancel user media request " << (*request_it)->request_id;
// If the request is not generated, it means that a request
// has been sent to the MediaStreamDispatcher to generate a stream
// but MediaStreamDispatcher has not yet responded and we need to cancel
// the request.
if (!(*request_it)->generated) {
media_stream_dispatcher_->CancelGenerateStream(
(*request_it)->request_id, weak_factory_.GetWeakPtr());
}
request_it = user_media_requests_.erase(request_it);
}
// Loop through all current local sources and stop the sources. // Loop through all current local sources and stop the sources.
LocalStreamSources::iterator sources_it = local_sources_.begin(); LocalStreamSources::iterator sources_it = local_sources_.begin();
...@@ -910,4 +926,8 @@ void MediaStreamImpl::UserMediaRequestInfo::RemoveSource( ...@@ -910,4 +926,8 @@ void MediaStreamImpl::UserMediaRequestInfo::RemoveSource(
} }
} }
bool MediaStreamImpl::UserMediaRequestInfo::HasPendingSources() const {
return !sources_waiting_for_callback_.empty();
}
} // namespace content } // namespace content
...@@ -146,7 +146,7 @@ class CONTENT_EXPORT MediaStreamImpl ...@@ -146,7 +146,7 @@ class CONTENT_EXPORT MediaStreamImpl
bool IsSourceUsed(const blink::WebMediaStreamSource& source) const; bool IsSourceUsed(const blink::WebMediaStreamSource& source) const;
void RemoveSource(const blink::WebMediaStreamSource& source); void RemoveSource(const blink::WebMediaStreamSource& source);
bool AreAllSourcesRemoved() const { return sources_.empty(); } bool HasPendingSources() const;
private: private:
void OnTrackStarted(MediaStreamSource* source, bool success); void OnTrackStarted(MediaStreamSource* source, bool success);
...@@ -191,10 +191,15 @@ class CONTENT_EXPORT MediaStreamImpl ...@@ -191,10 +191,15 @@ class CONTENT_EXPORT MediaStreamImpl
UserMediaRequestInfo* request, UserMediaRequestInfo* request,
content::MediaStreamRequestResult result); content::MediaStreamRequestResult result);
void OnStreamGeneratedForCancelledRequest(
const StreamDeviceInfoArray& audio_array,
const StreamDeviceInfoArray& video_array);
UserMediaRequestInfo* FindUserMediaRequestInfo(int request_id); UserMediaRequestInfo* FindUserMediaRequestInfo(int request_id);
UserMediaRequestInfo* FindUserMediaRequestInfo( UserMediaRequestInfo* FindUserMediaRequestInfo(
const blink::WebUserMediaRequest& request); const blink::WebUserMediaRequest& request);
void DeleteUserMediaRequestInfo(UserMediaRequestInfo* request); void DeleteUserMediaRequestInfo(UserMediaRequestInfo* request);
void DeleteAllUserMediaRequests();
MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(int request_id); MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(int request_id);
MediaDevicesRequestInfo* FindMediaDevicesRequestInfo( MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(
......
...@@ -8,6 +8,12 @@ ...@@ -8,6 +8,12 @@
namespace content { namespace content {
void LogUserMediaRequestWithNoResult(MediaStreamRequestState state) {
UMA_HISTOGRAM_ENUMERATION("WebRTC.UserMediaRequest.NoResultState",
state,
NUM_MEDIA_STREAM_REQUEST_WITH_NO_RESULT);
}
void LogUserMediaRequestResult(MediaStreamRequestResult result) { void LogUserMediaRequestResult(MediaStreamRequestResult result) {
UMA_HISTOGRAM_ENUMERATION( UMA_HISTOGRAM_ENUMERATION(
"WebRTC.UserMediaRequest.Result", result, NUM_MEDIA_REQUEST_RESULTS); "WebRTC.UserMediaRequest.Result", result, NUM_MEDIA_REQUEST_RESULTS);
......
...@@ -12,6 +12,21 @@ ...@@ -12,6 +12,21 @@
namespace content { namespace content {
// Used to investigate where UserMediaRequests end up.
// Only UserMediaRequests that do not log with LogUserMediaRequestResult
// should call LogUserMediaRequestWithNoResult.
//
// Elements in this enum should not be deleted or rearranged; the only
// permitted operation is to add new elements before
// NUM_MEDIA_STREAM_REQUEST_WITH_NO_RESULT.
enum MediaStreamRequestState {
MEDIA_STREAM_REQUEST_EXPLICITLY_CANCELLED = 0,
MEDIA_STREAM_REQUEST_NOT_GENERATED = 1,
MEDIA_STREAM_REQUEST_PENDING_MEDIA_TRACKS = 2,
NUM_MEDIA_STREAM_REQUEST_WITH_NO_RESULT
};
void LogUserMediaRequestWithNoResult(MediaStreamRequestState state);
void LogUserMediaRequestResult(MediaStreamRequestResult result); void LogUserMediaRequestResult(MediaStreamRequestResult result);
// Helper enum used for histogramming calls to WebRTC APIs from JavaScript. // Helper enum used for histogramming calls to WebRTC APIs from JavaScript.
......
...@@ -35798,6 +35798,20 @@ Therefore, the affected-histogram name has to have at least one dot in it. ...@@ -35798,6 +35798,20 @@ Therefore, the affected-histogram name has to have at least one dot in it.
</summary> </summary>
</histogram> </histogram>
<histogram name="WebRTC.UserMediaRequest.NoResultState"
enum="MediaStreamRequestState">
<owner>andresp@chromium.org</owner>
<summary>
The state of a UserMediaRequest when it gets destroyed before having a
result.
Note: &quot;Explicitly Cancelled&quot; means
MediaStreamImpl::cancelUserMediaRequest was called and not necessarily that
the user cancelled. Those are likely tracked as UserMediaRequest with a
result of permission denied.
</summary>
</histogram>
<histogram name="WebRTC.UserMediaRequest.Result" <histogram name="WebRTC.UserMediaRequest.Result"
enum="MediaStreamRequestResult"> enum="MediaStreamRequestResult">
<owner>andresp@chromium.org</owner> <owner>andresp@chromium.org</owner>
...@@ -43332,6 +43346,12 @@ Therefore, the affected-histogram name has to have at least one dot in it. ...@@ -43332,6 +43346,12 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="8" label="Track Start Failure"/> <int value="8" label="Track Start Failure"/>
</enum> </enum>
<enum name="MediaStreamRequestState" type="int">
<int value="0" label="Explicitly Cancelled"/>
<int value="1" label="Stream Not Generated"/>
<int value="2" label="Pending Media Tracks"/>
</enum>
<enum name="MetaTagTypeEnum" type="int"> <enum name="MetaTagTypeEnum" type="int">
<int value="0" label="No viewport tag"/> <int value="0" label="No viewport tag"/>
<int value="1" label="Viewport meta with device width"/> <int value="1" label="Viewport meta with device width"/>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment