Commit e976c3c5 authored by qinmin@chromium.org's avatar qinmin@chromium.org

Turn webspeech on/off when tab goes fore/background

This change adds a toggle to turn webspeech off when tab goes background.
And further request to turn media capture devices on will be denied.
So Both WebRTC and webSpeech won't be able to initiate new requests when tab is in background.

This CL also fixed a bug in the original CL that was reverted: some times recognition will not be aborted immediately after screen lock.
The issue is caused by that calling abort() will not delete the session in SpeechRecognitionManagerImpl.
So if a SpeechRecognition objects calls multiple start(), several sessions with the same request_id will be created.
And when passing the request_id to abort the sessions, only 1 session will be aborted
This change requests the all sessions in the same render view to be aborted.
Thus solving the above issue.

BUG=396054
R=jochen@chromium.org, tsepez@chromium.org, xians@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285314 0039d316-1c4b-4281-b951-d872f2087c98
parent 52d80b57
......@@ -23,6 +23,7 @@
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/media_stream_request.h"
#include "extensions/common/constants.h"
#include "grit/generated_resources.h"
......@@ -662,7 +663,7 @@ bool MediaStreamDevicesController::IsDeviceAudioCaptureRequestedAndAllowed()
const {
MediaStreamTypeSettingsMap::const_iterator it =
request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE);
return (it != request_permissions_.end() &&
return (it != request_permissions_.end() && IsCaptureDeviceRequestAllowed() &&
it->second.permission == MEDIA_ALLOWED);
}
......@@ -670,6 +671,15 @@ bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed()
const {
MediaStreamTypeSettingsMap::const_iterator it =
request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE);
return (it != request_permissions_.end() &&
return (it != request_permissions_.end() && IsCaptureDeviceRequestAllowed() &&
it->second.permission == MEDIA_ALLOWED);
}
bool MediaStreamDevicesController::IsCaptureDeviceRequestAllowed() const {
#if defined(OS_ANDROID)
// Don't approve device requests if the tab was hidden.
// TODO(qinmin): Add a test for this. http://crbug.com/396869.
return web_contents_->GetRenderWidgetHostView()->IsShowing();
#endif
return true;
}
......@@ -138,6 +138,10 @@ class MediaStreamDevicesController : public PermissionBubbleRequest {
bool IsDeviceAudioCaptureRequestedAndAllowed() const;
bool IsDeviceVideoCaptureRequestedAndAllowed() const;
// Returns true if media capture device is allowed to be used. This could
// return false when tab goes to background.
bool IsCaptureDeviceRequestAllowed() const;
content::WebContents* web_contents_;
// The owner of this class needs to make sure it does not outlive the profile.
......
......@@ -52,6 +52,8 @@ bool SpeechRecognitionDispatcherHost::OnMessageReceived(
OnAbortRequest)
IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_StopCaptureRequest,
OnStopCaptureRequest)
IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_AbortAllRequests,
OnAbortAllRequests)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
......@@ -173,6 +175,11 @@ void SpeechRecognitionDispatcherHost::OnAbortRequest(int render_view_id,
SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
}
void SpeechRecognitionDispatcherHost::OnAbortAllRequests(int render_view_id) {
SpeechRecognitionManager::GetInstance()->AbortAllSessionsForRenderView(
render_process_id_, render_view_id);
}
void SpeechRecognitionDispatcherHost::OnStopCaptureRequest(
int render_view_id, int request_id) {
int session_id = SpeechRecognitionManager::GetInstance()->GetSession(
......
......@@ -72,6 +72,7 @@ class CONTENT_EXPORT SpeechRecognitionDispatcherHost
bool filter_profanities);
void OnAbortRequest(int render_view_id, int request_id);
void OnStopCaptureRequest(int render_view_id, int request_id);
void OnAbortAllRequests(int render_view_id);
int render_process_id_;
scoped_refptr<net::URLRequestContextGetter> context_getter_;
......
......@@ -70,12 +70,19 @@ IPC_MESSAGE_CONTROL1(SpeechRecognitionHostMsg_StartRequest,
SpeechRecognitionHostMsg_StartRequest_Params)
// Requests the speech recognition service to abort speech recognition on
// behalf of the given |render_view_id|. If speech recognition is not happening
// or is happening on behalf of some other render view, this call does nothing.
// behalf of the given |render_view_id| and |request_id|. If there are no
// sessions associated with the |request_id| in the render view, this call
// does nothing.
IPC_MESSAGE_CONTROL2(SpeechRecognitionHostMsg_AbortRequest,
int /* render_view_id */,
int /* request_id */)
// Requests the speech recognition service to abort all speech recognitions on
// behalf of the given |render_view_id|. If speech recognition is not happening
// or is happening on behalf of some other render view, this call does nothing.
IPC_MESSAGE_CONTROL1(SpeechRecognitionHostMsg_AbortAllRequests,
int /* render_view_id */)
// Requests the speech recognition service to stop audio capture on behalf of
// the given |render_view_id|. Any audio recorded so far will be fed to the
// speech recognizer. If speech recognition is not happening nor or is
......
......@@ -3563,6 +3563,8 @@ void RenderViewImpl::OnWasHidden() {
#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
RenderThreadImpl::current()->video_capture_impl_manager()->
SuspendDevices(true);
if (speech_recognition_dispatcher_)
speech_recognition_dispatcher_->AbortAllRecognitions();
#endif
if (webview())
......
......@@ -35,6 +35,11 @@ SpeechRecognitionDispatcher::SpeechRecognitionDispatcher(
SpeechRecognitionDispatcher::~SpeechRecognitionDispatcher() {
}
void SpeechRecognitionDispatcher::AbortAllRecognitions() {
Send(new SpeechRecognitionHostMsg_AbortAllRequests(
routing_id()));
}
bool SpeechRecognitionDispatcher::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
......
......@@ -28,6 +28,9 @@ class SpeechRecognitionDispatcher : public RenderViewObserver,
explicit SpeechRecognitionDispatcher(RenderViewImpl* render_view);
virtual ~SpeechRecognitionDispatcher();
// Aborts all speech recognitions.
void AbortAllRecognitions();
private:
// RenderViewObserver implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
......
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