diff options
8 files changed, 97 insertions, 60 deletions
diff --git a/chrome/browser/speech/speech_recognition_bubble.cc b/chrome/browser/speech/speech_recognition_bubble.cc index fa31bb3..7e4dea4 100644 --- a/chrome/browser/speech/speech_recognition_bubble.cc +++ b/chrome/browser/speech/speech_recognition_bubble.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/lazy_instance.h" #include "base/message_loop/message_loop.h" +#include "chrome/browser/tab_contents/tab_util.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" #include "grit/generated_resources.h" @@ -122,8 +123,11 @@ SpeechRecognitionBubble::FactoryMethod SpeechRecognitionBubble::factory_ = NULL; const int SpeechRecognitionBubble::kBubbleTargetOffsetX = 10; SpeechRecognitionBubble* SpeechRecognitionBubble::Create( - WebContents* web_contents, Delegate* delegate, + int render_process_id, int render_view_id, Delegate* delegate, const gfx::Rect& element_rect) { + WebContents* web_contents = + tab_util::GetWebContentsByID(render_process_id, render_view_id); + if (factory_) return (*factory_)(web_contents, delegate, element_rect); @@ -131,18 +135,21 @@ SpeechRecognitionBubble* SpeechRecognitionBubble::Create( if (!web_contents) return NULL; - return CreateNativeBubble(web_contents, delegate, element_rect); + return CreateNativeBubble(render_process_id, render_view_id, + delegate, element_rect); } SpeechRecognitionBubbleBase::SpeechRecognitionBubbleBase( - WebContents* web_contents) + int render_process_id, int render_view_id) : weak_factory_(this), animation_step_(0), display_mode_(DISPLAY_MODE_RECORDING), - web_contents_(web_contents), + render_process_id_(render_process_id), + render_view_id_(render_view_id), scale_(1.0f) { + WebContents* web_contents = GetWebContents(); gfx::NativeView view = - web_contents_ ? web_contents_->GetView()->GetNativeView() : NULL; + web_contents ? web_contents->GetView()->GetNativeView() : NULL; gfx::Screen* screen = gfx::Screen::GetScreenFor(view); gfx::Display display = screen->GetDisplayNearestWindow(view); scale_ = display.device_scale_factor(); @@ -263,7 +270,7 @@ void SpeechRecognitionBubbleBase::SetInputVolume(float volume, } WebContents* SpeechRecognitionBubbleBase::GetWebContents() { - return web_contents_; + return tab_util::GetWebContentsByID(render_process_id_, render_view_id_); } void SpeechRecognitionBubbleBase::SetImage(const gfx::ImageSkia& image) { diff --git a/chrome/browser/speech/speech_recognition_bubble.h b/chrome/browser/speech/speech_recognition_bubble.h index 6ca5a73..96a805e 100644 --- a/chrome/browser/speech/speech_recognition_bubble.h +++ b/chrome/browser/speech/speech_recognition_bubble.h @@ -57,17 +57,21 @@ class SpeechRecognitionBubble { // Factory method to create new instances. // Creates the bubble, call |Show| to display it on screen. - // |web_contents| is the WebContents hosting the page. + // |render_process_id| and |render_view_id| is used to extract the + // correct WebContents. // |element_rect| is the display bounds of the html element requesting speech // recognition (in page coordinates). - static SpeechRecognitionBubble* Create(content::WebContents* web_contents, - Delegate* delegate, - const gfx::Rect& element_rect); + static SpeechRecognitionBubble* Create( + int render_process_id, + int render_view_id, + Delegate* delegate, + const gfx::Rect& element_rect); // This is implemented by platform specific code to create the underlying // bubble window. Not to be called directly by users of this class. static SpeechRecognitionBubble* CreateNativeBubble( - content::WebContents* web_contents, + int render_process_id, + int render_view_id, Delegate* delegate, const gfx::Rect& element_rect); @@ -135,7 +139,7 @@ class SpeechRecognitionBubbleBase : public SpeechRecognitionBubble { DISPLAY_MODE_MESSAGE }; - explicit SpeechRecognitionBubbleBase(content::WebContents* web_contents); + SpeechRecognitionBubbleBase(int render_process_id, int render_view_id); virtual ~SpeechRecognitionBubbleBase(); // SpeechRecognitionBubble methods @@ -179,8 +183,11 @@ class SpeechRecognitionBubbleBase : public SpeechRecognitionBubble { scoped_ptr<SkBitmap> mic_image_; // A temporary buffer image used in creating the above mic image. scoped_ptr<SkBitmap> buffer_image_; - // WebContents in which this this bubble gets displayed. - content::WebContents* web_contents_; + + // Content in which this bubble gets displayed. + int render_process_id_; + int render_view_id_; + // The current image displayed in the bubble's icon widget. gfx::ImageSkia icon_image_; // The scale factor used for the web-contents. diff --git a/chrome/browser/speech/speech_recognition_bubble_browsertest.cc b/chrome/browser/speech/speech_recognition_bubble_browsertest.cc index edc5160..dcb35f4 100644 --- a/chrome/browser/speech/speech_recognition_bubble_browsertest.cc +++ b/chrome/browser/speech/speech_recognition_bubble_browsertest.cc @@ -7,6 +7,9 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/rect.h" @@ -24,26 +27,35 @@ class SpeechRecognitionBubbleTest : public SpeechRecognitionBubbleDelegate, IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, CreateAndDestroy) { gfx::Rect element_rect(100, 100, 100, 100); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); scoped_ptr<SpeechRecognitionBubble> bubble(SpeechRecognitionBubble::Create( - browser()->tab_strip_model()->GetActiveWebContents(), - this, element_rect)); + web_contents->GetRenderProcessHost()->GetID(), + web_contents->GetRenderViewHost()->GetRoutingID(), + this, element_rect)); EXPECT_TRUE(bubble.get()); } IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, ShowAndDestroy) { gfx::Rect element_rect(100, 100, 100, 100); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); scoped_ptr<SpeechRecognitionBubble> bubble(SpeechRecognitionBubble::Create( - browser()->tab_strip_model()->GetActiveWebContents(), - this, element_rect)); + web_contents->GetRenderProcessHost()->GetID(), + web_contents->GetRenderViewHost()->GetRoutingID(), + this, element_rect)); EXPECT_TRUE(bubble.get()); bubble->Show(); } IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, ShowAndHide) { gfx::Rect element_rect(100, 100, 100, 100); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); scoped_ptr<SpeechRecognitionBubble> bubble(SpeechRecognitionBubble::Create( - browser()->tab_strip_model()->GetActiveWebContents(), - this, element_rect)); + web_contents->GetRenderProcessHost()->GetID(), + web_contents->GetRenderViewHost()->GetRoutingID(), + this, element_rect)); EXPECT_TRUE(bubble.get()); bubble->Show(); bubble->Hide(); @@ -51,9 +63,12 @@ IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, ShowAndHide) { IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, ShowAndHideTwice) { gfx::Rect element_rect(100, 100, 100, 100); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); scoped_ptr<SpeechRecognitionBubble> bubble(SpeechRecognitionBubble::Create( - browser()->tab_strip_model()->GetActiveWebContents(), - this, element_rect)); + web_contents->GetRenderProcessHost()->GetID(), + web_contents->GetRenderViewHost()->GetRoutingID(), + this, element_rect)); EXPECT_TRUE(bubble.get()); bubble->Show(); bubble->Hide(); diff --git a/chrome/browser/speech/speech_recognition_bubble_controller.cc b/chrome/browser/speech/speech_recognition_bubble_controller.cc index ff7aadd..ede3858 100644 --- a/chrome/browser/speech/speech_recognition_bubble_controller.cc +++ b/chrome/browser/speech/speech_recognition_bubble_controller.cc @@ -168,8 +168,7 @@ void SpeechRecognitionBubbleController::ProcessRequestInUiThread( switch (request.type) { case REQUEST_CREATE: bubble_.reset(SpeechRecognitionBubble::Create( - tab_util::GetWebContentsByID(request.render_process_id, - request.render_view_id), + request.render_process_id, request.render_view_id, this, request.element_rect)); if (!bubble_.get()) { diff --git a/chrome/browser/speech/speech_recognition_bubble_controller_unittest.cc b/chrome/browser/speech/speech_recognition_bubble_controller_unittest.cc index f1380c9..8e4f0c9 100644 --- a/chrome/browser/speech/speech_recognition_bubble_controller_unittest.cc +++ b/chrome/browser/speech/speech_recognition_bubble_controller_unittest.cc @@ -11,10 +11,13 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/testing_profile.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/test/test_browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/rect.h" + using content::BrowserThread; using content::WebContents; @@ -30,10 +33,9 @@ class MockSpeechRecognitionBubble : public SpeechRecognitionBubbleBase { BUBBLE_TEST_CLICK_TRY_AGAIN, }; - MockSpeechRecognitionBubble(WebContents* web_contents, - Delegate* delegate, - const gfx::Rect&) - : SpeechRecognitionBubbleBase(web_contents) { + MockSpeechRecognitionBubble(int render_process_id, int render_view_id, + Delegate* delegate, const gfx::Rect&) + : SpeechRecognitionBubbleBase(render_process_id, render_view_id) { VLOG(1) << "MockSpeechRecognitionBubble created"; base::MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&InvokeDelegate, delegate)); @@ -141,15 +143,7 @@ class SpeechRecognitionBubbleControllerTest base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&ActivateBubble)); - // The |web_contents| parameter would be NULL since the dummy session id - // passed to CreateBubble would not have matched any active tab. So get a - // real WebContents pointer from the test fixture and pass that, because - // the bubble controller registers for tab close notifications which need - // a valid WebContents. - web_contents = - test_fixture_->browser()->tab_strip_model()->GetActiveWebContents(); - return new MockSpeechRecognitionBubble(web_contents, delegate, - element_rect); + return new MockSpeechRecognitionBubble(0, 0, delegate, element_rect); } protected: diff --git a/chrome/browser/ui/cocoa/speech_recognition_bubble_cocoa.mm b/chrome/browser/ui/cocoa/speech_recognition_bubble_cocoa.mm index c308f5a..8c65dad 100644 --- a/chrome/browser/ui/cocoa/speech_recognition_bubble_cocoa.mm +++ b/chrome/browser/ui/cocoa/speech_recognition_bubble_cocoa.mm @@ -25,7 +25,8 @@ namespace { // for more information on how this gets used. class SpeechRecognitionBubbleImpl : public SpeechRecognitionBubbleBase { public: - SpeechRecognitionBubbleImpl(WebContents* web_contents, + SpeechRecognitionBubbleImpl(int render_process_id, + int render_view_id, Delegate* delegate, const gfx::Rect& element_rect); virtual ~SpeechRecognitionBubbleImpl(); @@ -41,10 +42,11 @@ class SpeechRecognitionBubbleImpl : public SpeechRecognitionBubbleBase { }; SpeechRecognitionBubbleImpl::SpeechRecognitionBubbleImpl( - WebContents* web_contents, + int render_process_id, + int render_view_id, Delegate* delegate, const gfx::Rect& element_rect) - : SpeechRecognitionBubbleBase(web_contents), + : SpeechRecognitionBubbleBase(render_process_id, render_view_id), delegate_(delegate), element_rect_(element_rect) { } @@ -55,11 +57,14 @@ SpeechRecognitionBubbleImpl::~SpeechRecognitionBubbleImpl() { } void SpeechRecognitionBubbleImpl::UpdateImage() { - if (window_.get()) + if (window_.get() && GetWebContents()) [window_.get() setImage:gfx::NSImageFromImageSkia(icon_image())]; } void SpeechRecognitionBubbleImpl::Show() { + if (!GetWebContents()) + return; + if (window_.get()) { [window_.get() show]; return; @@ -115,7 +120,7 @@ void SpeechRecognitionBubbleImpl::Hide() { } void SpeechRecognitionBubbleImpl::UpdateLayout() { - if (!window_.get()) + if (!window_.get() || !GetWebContents()) return; [window_.get() updateLayout:display_mode() @@ -126,8 +131,12 @@ void SpeechRecognitionBubbleImpl::UpdateLayout() { } // namespace SpeechRecognitionBubble* SpeechRecognitionBubble::CreateNativeBubble( - WebContents* web_contents, + int render_process_id, + int render_view_id, Delegate* delegate, const gfx::Rect& element_rect) { - return new SpeechRecognitionBubbleImpl(web_contents, delegate, element_rect); + return new SpeechRecognitionBubbleImpl(render_process_id, + render_view_id, + delegate, + element_rect); } diff --git a/chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc b/chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc index e48a7041..d9e580f 100644 --- a/chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc +++ b/chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc @@ -45,7 +45,7 @@ const GdkColor& kLabelTextColor = ui::kGdkBlack; class SpeechRecognitionBubbleGtk : public SpeechRecognitionBubbleBase, public BubbleDelegateGtk { public: - SpeechRecognitionBubbleGtk(WebContents* web_contents, + SpeechRecognitionBubbleGtk(int render_process_id, int render_view_id, Delegate* delegate, const gfx::Rect& element_rect); virtual ~SpeechRecognitionBubbleGtk(); @@ -80,9 +80,9 @@ class SpeechRecognitionBubbleGtk : public SpeechRecognitionBubbleBase, }; SpeechRecognitionBubbleGtk::SpeechRecognitionBubbleGtk( - WebContents* web_contents, Delegate* delegate, + int render_process_id, int render_view_id, Delegate* delegate, const gfx::Rect& element_rect) - : SpeechRecognitionBubbleBase(web_contents), + : SpeechRecognitionBubbleBase(render_process_id, render_process_id), delegate_(delegate), bubble_(NULL), element_rect_(element_rect), @@ -117,7 +117,7 @@ void SpeechRecognitionBubbleGtk::OnMicSettingsClicked(GtkWidget* widget) { } void SpeechRecognitionBubbleGtk::Show() { - if (bubble_) + if (bubble_ || !GetWebContents()) return; // Nothing further to do since the bubble is already visible. // We use a vbox to arrange the controls (label, image, button bar) vertically @@ -212,7 +212,7 @@ void SpeechRecognitionBubbleGtk::Hide() { } void SpeechRecognitionBubbleGtk::UpdateLayout() { - if (!bubble_) + if (!bubble_ || !GetWebContents()) return; if (display_mode() == DISPLAY_MODE_MESSAGE) { @@ -293,8 +293,9 @@ void SpeechRecognitionBubbleGtk::BubbleClosing(BubbleGtk* bubble, } // namespace SpeechRecognitionBubble* SpeechRecognitionBubble::CreateNativeBubble( - WebContents* web_contents, - Delegate* delegate, + int render_process_id, int render_view_id, + SpeechRecognitionBubble::Delegate* delegate, const gfx::Rect& element_rect) { - return new SpeechRecognitionBubbleGtk(web_contents, delegate, element_rect); + return new SpeechRecognitionBubbleGtk(render_process_id, render_view_id, + delegate, element_rect); } diff --git a/chrome/browser/ui/views/speech_recognition_bubble_views.cc b/chrome/browser/ui/views/speech_recognition_bubble_views.cc index 0e4a0eb..33a9735 100644 --- a/chrome/browser/ui/views/speech_recognition_bubble_views.cc +++ b/chrome/browser/ui/views/speech_recognition_bubble_views.cc @@ -315,7 +315,7 @@ void SpeechRecognitionBubbleView::Layout() { // Implementation of SpeechRecognitionBubble. class SpeechRecognitionBubbleImpl : public SpeechRecognitionBubbleBase { public: - SpeechRecognitionBubbleImpl(WebContents* web_contents, + SpeechRecognitionBubbleImpl(int render_process_id, int render_view_id, Delegate* delegate, const gfx::Rect& element_rect); virtual ~SpeechRecognitionBubbleImpl(); @@ -337,9 +337,9 @@ class SpeechRecognitionBubbleImpl : public SpeechRecognitionBubbleBase { }; SpeechRecognitionBubbleImpl::SpeechRecognitionBubbleImpl( - WebContents* web_contents, Delegate* delegate, + int render_process_id, int render_view_id, Delegate* delegate, const gfx::Rect& element_rect) - : SpeechRecognitionBubbleBase(web_contents), + : SpeechRecognitionBubbleBase(render_process_id, render_view_id), delegate_(delegate), bubble_(NULL), element_rect_(element_rect) { @@ -353,11 +353,14 @@ SpeechRecognitionBubbleImpl::~SpeechRecognitionBubbleImpl() { } void SpeechRecognitionBubbleImpl::Show() { + WebContents* web_contents = GetWebContents(); + if (!web_contents) + return; + if (!bubble_) { views::View* icon = NULL; // Anchor to the location bar, in case |element_rect| is offscreen. - WebContents* web_contents = GetWebContents(); Browser* browser = chrome::FindBrowserWithWebContents(web_contents); if (browser) { BrowserView* browser_view = @@ -388,20 +391,22 @@ void SpeechRecognitionBubbleImpl::Hide() { } void SpeechRecognitionBubbleImpl::UpdateLayout() { - if (bubble_) + if (bubble_ && GetWebContents()) bubble_->UpdateLayout(display_mode(), message_text(), icon_image()); } void SpeechRecognitionBubbleImpl::UpdateImage() { - if (bubble_) + if (bubble_ && GetWebContents()) bubble_->SetImage(icon_image()); } } // namespace SpeechRecognitionBubble* SpeechRecognitionBubble::CreateNativeBubble( - WebContents* web_contents, + int render_process_id, + int render_view_id, SpeechRecognitionBubble::Delegate* delegate, const gfx::Rect& element_rect) { - return new SpeechRecognitionBubbleImpl(web_contents, delegate, element_rect); + return new SpeechRecognitionBubbleImpl(render_process_id, render_view_id, + delegate, element_rect); } |