Commit ada65a7b authored by lazyboy's avatar lazyboy Committed by Commit bot

Fix speech crash on render view swap.

ChromeSRMDelegate should not be reading the WebContents* back from
  WebContentsObserver after it has explicitly set to observe nullptr
  WebContents.
This was introduced by my earlier CL: r330213, I never tested the
  feature from NTP.

BUG=489182, 489157
Test=1) From new tab page, click on the mic beside search box,
  feed it some search query, it should not crash chrome.
2) Similar to step #1, but before the query completes, close the
  tab, observe no crash.

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

Cr-Commit-Position: refs/heads/master@{#330784}
parent de10703e
......@@ -166,9 +166,9 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher
return;
// Avoid multiple registrations for the same |web_contents|.
if (FindWebContents(web_contents) != registered_web_contents_.end()) {
if (FindWebContents(web_contents) != registered_web_contents_.end())
return;
}
registered_web_contents_.push_back(new WebContentsTracker(
web_contents, base::Bind(&TabWatcher::OnTabClosed,
// |this| outlives WebContentsTracker.
......@@ -195,6 +195,7 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher
int render_process_id,
int render_view_id)
: content::WebContentsObserver(web_contents),
web_contents_(web_contents),
finished_callback_(finished_callback),
render_process_id_(render_process_id),
render_view_id_(render_view_id) {}
......@@ -203,6 +204,7 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher
int render_process_id() const { return render_process_id_; }
int render_view_id() const { return render_view_id_; }
const content::WebContents* GetWebContents() const { return web_contents_; }
private:
// content::WebContentsObserver overrides.
......@@ -218,6 +220,13 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher
// NOTE: We are deleted now.
}
// Raw pointer to our WebContents.
//
// Although we are a WebContentsObserver, calling
// WebContents::web_contents() would return NULL once we unregister
// ourselves in WebContentsDestroyed() or RenderViewHostChanged(). So we
// store a reference to perform cleanup.
const content::WebContents* const web_contents_;
const base::Closure finished_callback_;
const int render_process_id_;
const int render_view_id_;
......@@ -238,7 +247,7 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher
for (ScopedVector<WebContentsTracker>::iterator i(
registered_web_contents_.begin());
i != registered_web_contents_.end(); ++i) {
if ((*i)->web_contents() == web_contents)
if ((*i)->GetWebContents() == web_contents)
return i;
}
......
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