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

Unified Diff: content/browser/speech/speech_recognition_dispatcher_host.cc

Issue 636863003: Make SpeechRecognition per RenderFrame instead of per RenderView. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review comments Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/speech/speech_recognition_dispatcher_host.cc
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.cc b/content/browser/speech/speech_recognition_dispatcher_host.cc
index f920c51e779d6632c6eab3f1c8ee304080c789aa..737a610f48fad5ebb29e65e67e27db11b4dbfed6 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.cc
+++ b/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -9,23 +9,77 @@
#include "base/lazy_instance.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/speech/speech_recognition_manager_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/speech_recognition_messages.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/speech_recognition_manager_delegate.h"
#include "content/public/browser/speech_recognition_session_config.h"
#include "content/public/browser/speech_recognition_session_context.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/child_process_host.h"
namespace content {
+namespace {
+
+void SendMessageToFrameOnUI(int render_process_id,
+ int render_frame_id,
+ IPC::Message* message) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ RenderFrameHost* render_frame_host =
+ RenderFrameHost::FromID(render_process_id, render_frame_id);
+ if (render_frame_host)
+ render_frame_host->Send(message);
+}
+
+void SendMessageToFrame(int render_process_id,
+ int render_frame_id,
+ IPC::Message* message) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&SendMessageToFrameOnUI,
+ render_process_id, render_frame_id, message));
+}
+
+} // anonymous namespace
+
+using FrameDeletedCallback = base::Callback<void(int)>;
+using WebContentsDeletedCallback = base::Callback<void(WebContents*)>;
+
+class SpeechRecognitionDispatcherHost::FrameDeletedObserver
+ : public WebContentsObserver {
+ public:
+ FrameDeletedObserver(WebContents* web_contents,
+ FrameDeletedCallback frame_deleted_cb,
+ WebContentsDeletedCallback web_contents_deleted_cb)
+ : WebContentsObserver(web_contents) {
+ }
+
+ ~FrameDeletedObserver() override {
+ }
+
+ private:
+ void RenderFrameDeleted(RenderFrameHost* render_frame_host) override {
+ frame_deleted_cb_.Run(render_frame_host->GetRoutingID());
+ }
+
+ void WebContentsDestroyed() override {
+ web_contents_deleted_cb_.Run(web_contents());
+ }
+
+ const FrameDeletedCallback frame_deleted_cb_;
+ const WebContentsDeletedCallback web_contents_deleted_cb_;
+};
+
SpeechRecognitionDispatcherHost::SpeechRecognitionDispatcherHost(
- int render_process_id,
- net::URLRequestContextGetter* context_getter)
+ int render_process_id)
: BrowserMessageFilter(SpeechRecognitionMsgStart),
render_process_id_(render_process_id),
- context_getter_(context_getter),
weak_factory_(this) {
// Do not add any non-trivial initialization here, instead do it lazily when
// required (e.g. see the method |SpeechRecognitionManager::GetInstance()|) or
@@ -33,8 +87,11 @@ SpeechRecognitionDispatcherHost::SpeechRecognitionDispatcherHost(
}
SpeechRecognitionDispatcherHost::~SpeechRecognitionDispatcherHost() {
- SpeechRecognitionManager::GetInstance()->AbortAllSessionsForRenderProcess(
- render_process_id_);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ weak_factory_.InvalidateWeakPtrs();
+
+ STLDeleteContainerPairSecondPointers(frame_deleted_observers_.begin(),
+ frame_deleted_observers_.end());
}
base::WeakPtr<SpeechRecognitionDispatcherHost>
@@ -46,9 +103,20 @@ void SpeechRecognitionDispatcherHost::OnDestruct() const {
BrowserThread::DeleteOnIOThread::Destruct(this);
}
+void SpeechRecognitionDispatcherHost::OnChannelClosing() {
+ weak_factory_.InvalidateWeakPtrs();
+}
+
+void SpeechRecognitionDispatcherHost::OverrideThreadForMessage(
+ const IPC::Message& message, BrowserThread::ID* thread) {
+ if (message.type() == SpeechRecognitionHostMsg_StartRequest::ID)
+ *thread = BrowserThread::UI;
+}
+
bool SpeechRecognitionDispatcherHost::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
+
IPC_BEGIN_MESSAGE_MAP(SpeechRecognitionDispatcherHost, message)
IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_StartRequest,
OnStartRequest)
@@ -60,23 +128,13 @@ bool SpeechRecognitionDispatcherHost::OnMessageReceived(
OnAbortAllRequests)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void SpeechRecognitionDispatcherHost::OverrideThreadForMessage(
- const IPC::Message& message,
- BrowserThread::ID* thread) {
- if (message.type() == SpeechRecognitionHostMsg_StartRequest::ID)
- *thread = BrowserThread::UI;
-}
-void SpeechRecognitionDispatcherHost::OnChannelClosing() {
- weak_factory_.InvalidateWeakPtrs();
+ return handled;
}
void SpeechRecognitionDispatcherHost::OnStartRequest(
const SpeechRecognitionHostMsg_StartRequest_Params& params) {
- SpeechRecognitionHostMsg_StartRequest_Params input_params(params);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Check that the origin specified by the renderer process is one
// that it is allowed to access.
@@ -89,72 +147,60 @@ void SpeechRecognitionDispatcherHost::OnStartRequest(
}
int embedder_render_process_id = 0;
- int embedder_render_view_id = MSG_ROUTING_NONE;
- RenderViewHostImpl* render_view_host =
- RenderViewHostImpl::FromID(render_process_id_, params.render_view_id);
- if (!render_view_host) {
- // RVH can be null if the tab was closed while continuous mode speech
- // recognition was running. This seems to happen on mac.
- LOG(WARNING) << "SRDH::OnStartRequest, RenderViewHost does not exist";
- return;
- }
- WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
- WebContents::FromRenderViewHost(render_view_host));
- BrowserPluginGuest* guest = web_contents->GetBrowserPluginGuest();
+ int embedder_render_frame_id = MSG_ROUTING_NONE;
+
+ WebContents* web_contents = WebContents::FromRenderFrameHost(
+ RenderFrameHost::FromID(render_process_id_, params.render_frame_id));
+ DCHECK(web_contents);
+
+ BrowserPluginGuest* guest =
+ static_cast<WebContentsImpl*>(web_contents)->GetBrowserPluginGuest();
+
if (guest) {
// If the speech API request was from a guest, save the context of the
// embedder since we will use it to decide permission.
embedder_render_process_id =
guest->embedder_web_contents()->GetRenderProcessHost()->GetID();
DCHECK_NE(embedder_render_process_id, 0);
- embedder_render_view_id =
- guest->embedder_web_contents()->GetRenderViewHost()->GetRoutingID();
- DCHECK_NE(embedder_render_view_id, MSG_ROUTING_NONE);
+ embedder_render_frame_id =
+ guest->embedder_web_contents()->GetMainFrame()->GetRoutingID();
+ DCHECK_NE(embedder_render_frame_id, MSG_ROUTING_NONE);
}
- // TODO(lazyboy): Check if filter_profanities should use |render_process_id|
- // instead of |render_process_id_|.
bool filter_profanities =
SpeechRecognitionManagerImpl::GetInstance() &&
SpeechRecognitionManagerImpl::GetInstance()->delegate() &&
SpeechRecognitionManagerImpl::GetInstance()->delegate()->
FilterProfanities(render_process_id_);
- // TODO(miu): This is a hack to allow SpeechRecognition to operate with the
- // MediaStreamManager, which partitions requests per RenderFrame, not per
- // RenderView. http://crbug.com/390749
- const int params_render_frame_id = render_view_host ?
- render_view_host->GetMainFrame()->GetRoutingID() : MSG_ROUTING_NONE;
-
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&SpeechRecognitionDispatcherHost::OnStartRequestOnIO,
- this,
- embedder_render_process_id,
- embedder_render_view_id,
- input_params,
- params_render_frame_id,
- filter_profanities));
-}
-
-void SpeechRecognitionDispatcherHost::OnStartRequestOnIO(
- int embedder_render_process_id,
- int embedder_render_view_id,
- const SpeechRecognitionHostMsg_StartRequest_Params& params,
- int params_render_frame_id,
- bool filter_profanities) {
SpeechRecognitionSessionContext context;
context.context_name = params.origin_url;
context.render_process_id = render_process_id_;
- context.render_view_id = params.render_view_id;
- context.render_frame_id = params_render_frame_id;
+ context.render_frame_id = params.render_frame_id;
context.embedder_render_process_id = embedder_render_process_id;
- context.embedder_render_view_id = embedder_render_view_id;
+ context.embedder_render_frame_id = embedder_render_frame_id;
if (embedder_render_process_id)
- context.guest_render_view_id = params.render_view_id;
+ context.guest_render_frame_id = params.render_frame_id;
context.request_id = params.request_id;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&SpeechRecognitionDispatcherHost::StartSession,
+ base::Unretained(this),
+ params,
+ context,
+ base::Unretained(web_contents->GetBrowserContext()->
+ GetRequestContextForRenderProcess(render_process_id_)),
+ filter_profanities));
+}
+
+void SpeechRecognitionDispatcherHost::StartSession(
+ const SpeechRecognitionHostMsg_StartRequest_Params& params,
+ const SpeechRecognitionSessionContext& context,
+ net::URLRequestContextGetter* url_request_context_getter,
+ bool filter_profanities) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
SpeechRecognitionSessionConfig config;
config.is_legacy_api = false;
config.language = params.language;
@@ -162,7 +208,7 @@ void SpeechRecognitionDispatcherHost::OnStartRequestOnIO(
config.max_hypotheses = params.max_hypotheses;
config.origin_url = params.origin_url;
config.initial_context = context;
- config.url_request_context_getter = context_getter_.get();
+ config.url_request_context_getter = url_request_context_getter;
config.filter_profanities = filter_profanities;
config.continuous = params.continuous;
config.interim_results = params.interim_results;
@@ -174,10 +220,12 @@ void SpeechRecognitionDispatcherHost::OnStartRequestOnIO(
SpeechRecognitionManager::GetInstance()->StartSession(session_id);
}
-void SpeechRecognitionDispatcherHost::OnAbortRequest(int render_view_id,
+void SpeechRecognitionDispatcherHost::OnAbortRequest(int render_frame_id,
int request_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
int session_id = SpeechRecognitionManager::GetInstance()->GetSession(
- render_process_id_, render_view_id, request_id);
+ render_process_id_, render_frame_id, request_id);
// The renderer might provide an invalid |request_id| if the session was not
// started as expected, e.g., due to unsatisfied security requirements.
@@ -185,15 +233,19 @@ 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::OnAbortAllRequests(int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ SpeechRecognitionManager::GetInstance()->AbortAllSessionsForRenderFrame(
+ render_process_id_, render_frame_id);
}
void SpeechRecognitionDispatcherHost::OnStopCaptureRequest(
- int render_view_id, int request_id) {
+ int render_frame_id, int request_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
int session_id = SpeechRecognitionManager::GetInstance()->GetSession(
- render_process_id_, render_view_id, request_id);
+ render_process_id_, render_frame_id, request_id);
// The renderer might provide an invalid |request_id| if the session was not
// started as expected, e.g., due to unsatisfied security requirements.
@@ -203,48 +255,103 @@ void SpeechRecognitionDispatcherHost::OnStopCaptureRequest(
}
}
+void SpeechRecognitionDispatcherHost::CreateObserverFor(
+ WebContents* web_contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (frame_deleted_observers_.find(web_contents) !=
+ frame_deleted_observers_.end()) {
+ return;
+ }
+
+ frame_deleted_observers_.emplace(
+ web_contents,
+ new FrameDeletedObserver(
+ web_contents,
+ base::Bind(&SpeechRecognitionDispatcherHost::AbortAllRequestsFromUI,
+ AsWeakPtr()),
+ base::Bind(&SpeechRecognitionDispatcherHost::RemoveObserverFor,
+ AsWeakPtr())));
+}
+
+void SpeechRecognitionDispatcherHost::RemoveObserverFor(
+ WebContents* web_contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ FrameDeletedObservers::iterator it =
+ frame_deleted_observers_.find(web_contents);
+ if (it == frame_deleted_observers_.end())
+ return;
+
+ delete it->second;
+ frame_deleted_observers_.erase(web_contents);
+}
+
+void SpeechRecognitionDispatcherHost::AbortAllRequestsFromUI(
+ int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&SpeechRecognitionDispatcherHost::OnAbortAllRequests,
+ this,
+ render_frame_id));
+}
+
// -------- SpeechRecognitionEventListener interface implementation -----------
void SpeechRecognitionDispatcherHost::OnRecognitionStart(int session_id) {
const SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
- Send(new SpeechRecognitionMsg_Started(context.render_view_id,
- context.request_id));
+
+ SendMessageToFrame(context.render_process_id, context.render_frame_id,
+ new SpeechRecognitionMsg_Started(context.render_frame_id,
+ context.request_id));
}
void SpeechRecognitionDispatcherHost::OnAudioStart(int session_id) {
const SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
- Send(new SpeechRecognitionMsg_AudioStarted(context.render_view_id,
- context.request_id));
+
+ SendMessageToFrame(context.render_process_id, context.render_frame_id,
+ new SpeechRecognitionMsg_AudioStarted(
+ context.render_frame_id, context.request_id));
}
void SpeechRecognitionDispatcherHost::OnSoundStart(int session_id) {
const SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
- Send(new SpeechRecognitionMsg_SoundStarted(context.render_view_id,
- context.request_id));
+
+ SendMessageToFrame(context.render_process_id, context.render_frame_id,
+ new SpeechRecognitionMsg_SoundStarted(
+ context.render_frame_id, context.request_id));
}
void SpeechRecognitionDispatcherHost::OnSoundEnd(int session_id) {
const SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
- Send(new SpeechRecognitionMsg_SoundEnded(context.render_view_id,
- context.request_id));
+
+ SendMessageToFrame(context.render_process_id, context.render_frame_id,
+ new SpeechRecognitionMsg_SoundEnded(
+ context.render_frame_id, context.request_id));
}
void SpeechRecognitionDispatcherHost::OnAudioEnd(int session_id) {
const SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
- Send(new SpeechRecognitionMsg_AudioEnded(context.render_view_id,
- context.request_id));
+
+ SendMessageToFrame(context.render_process_id, context.render_frame_id,
+ new SpeechRecognitionMsg_AudioEnded(
+ context.render_frame_id, context.request_id));
}
void SpeechRecognitionDispatcherHost::OnRecognitionEnd(int session_id) {
const SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
- Send(new SpeechRecognitionMsg_Ended(context.render_view_id,
- context.request_id));
+
+ SendMessageToFrame(context.render_process_id, context.render_frame_id,
+ new SpeechRecognitionMsg_Ended(
+ context.render_frame_id, context.request_id));
}
void SpeechRecognitionDispatcherHost::OnRecognitionResults(
@@ -252,9 +359,10 @@ void SpeechRecognitionDispatcherHost::OnRecognitionResults(
const SpeechRecognitionResults& results) {
const SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
- Send(new SpeechRecognitionMsg_ResultRetrieved(context.render_view_id,
- context.request_id,
- results));
+
+ SendMessageToFrame(context.render_process_id, context.render_frame_id,
+ new SpeechRecognitionMsg_ResultRetrieved(
+ context.render_frame_id, context.request_id, results));
}
void SpeechRecognitionDispatcherHost::OnRecognitionError(
@@ -262,9 +370,10 @@ void SpeechRecognitionDispatcherHost::OnRecognitionError(
const SpeechRecognitionError& error) {
const SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
- Send(new SpeechRecognitionMsg_ErrorOccurred(context.render_view_id,
- context.request_id,
- error));
+
+ SendMessageToFrame(context.render_process_id, context.render_frame_id,
+ new SpeechRecognitionMsg_ErrorOccurred(
+ context.render_frame_id, context.request_id, error));
}
// The events below are currently not used by speech JS APIs implementation.
« no previous file with comments | « content/browser/speech/speech_recognition_dispatcher_host.h ('k') | content/browser/speech/speech_recognition_manager_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698