// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_H_ #define CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_H_ #include <vector> #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "ui/base/layout.h" #include "ui/gfx/image/image_skia.h" class SkBitmap; class SkCanvas; namespace content { class WebContents; } namespace gfx { class Canvas; class Rect; } // SpeechRecognitionBubble displays a popup info bubble during speech // recognition, points to the html element which requested speech recognition // and shows progress events. The popup is closed by the user clicking anywhere // outside the popup window, or by the caller destroying this object. class SpeechRecognitionBubble { public: // The various buttons which may be part of the bubble. enum Button { BUTTON_TRY_AGAIN, BUTTON_CANCEL }; // Informs listeners of user actions in the bubble. class Delegate { public: // Invoked when the user selects a button in the info bubble. The InfoBubble // is still active and the caller should close it if necessary. virtual void InfoBubbleButtonClicked(Button button) = 0; // Invoked when the user clicks outside the InfoBubble causing it to close. // The InfoBubble window is no longer visible on screen and the caller can // free the InfoBubble instance. This callback is not issued if the bubble // got closed because the object was destroyed by the caller. virtual void InfoBubbleFocusChanged() = 0; protected: virtual ~Delegate() { } }; // Factory method to create new instances. // Creates the bubble, call |Show| to display it on screen. // |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( 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( int render_process_id, int render_view_id, Delegate* delegate, const gfx::Rect& element_rect); // |Create| uses the currently registered FactoryMethod to create the // SpeechRecognitionBubble instances. FactoryMethod is intended for testing. typedef SpeechRecognitionBubble* (*FactoryMethod)(content::WebContents*, Delegate*, const gfx::Rect&); // Sets the factory used by the static method Create. SpeechRecognitionBubble // does not take ownership of |factory|. A value of NULL results in a // SpeechRecognitionBubble being created directly. #if defined(UNIT_TEST) static void set_factory(FactoryMethod factory) { factory_ = factory; } #endif virtual ~SpeechRecognitionBubble() {} // Indicates to the user that audio hardware is initializing. If the bubble is // hidden, |Show| must be called to make it appear on screen. virtual void SetWarmUpMode() = 0; // Indicates to the user that audio recording is in progress. If the bubble is // hidden, |Show| must be called to make it appear on screen. virtual void SetRecordingMode() = 0; // Indicates to the user that recognition is in progress. If the bubble is // hidden, |Show| must be called to make it appear on screen. virtual void SetRecognizingMode() = 0; // Displays the given string with the 'Try again' and 'Cancel' buttons. If the // bubble is hidden, |Show| must be called to make it appear on screen. virtual void SetMessage(const base::string16& text) = 0; // Brings up the bubble on screen. virtual void Show() = 0; // Hides the info bubble, resulting in a call to // |Delegate::InfoBubbleFocusChanged| as well. virtual void Hide() = 0; // Updates and draws the current captured audio volume displayed on screen. virtual void SetInputVolume(float volume, float noise_volume) = 0; // Returns the WebContents for which this bubble gets displayed. virtual content::WebContents* GetWebContents() = 0; // The horizontal distance between the start of the html widget and the speech // bubble's arrow. static const int kBubbleTargetOffsetX; private: static FactoryMethod factory_; }; // Base class for the platform specific bubble implementations, this contains // the platform independent code for SpeechRecognitionBubble. class SpeechRecognitionBubbleBase : public SpeechRecognitionBubble { public: // The current display mode of the bubble, useful only for the platform // specific implementation. enum DisplayMode { DISPLAY_MODE_WARM_UP, DISPLAY_MODE_RECORDING, DISPLAY_MODE_RECOGNIZING, DISPLAY_MODE_MESSAGE }; SpeechRecognitionBubbleBase(int render_process_id, int render_view_id); virtual ~SpeechRecognitionBubbleBase(); // SpeechRecognitionBubble methods virtual void SetWarmUpMode() OVERRIDE; virtual void SetRecordingMode() OVERRIDE; virtual void SetRecognizingMode() OVERRIDE; virtual void SetMessage(const base::string16& text) OVERRIDE; virtual void SetInputVolume(float volume, float noise_volume) OVERRIDE; virtual content::WebContents* GetWebContents() OVERRIDE; protected: // Updates the platform specific UI layout for the current display mode. virtual void UpdateLayout() = 0; // Overridden by subclasses to copy |icon_image()| to the screen. virtual void UpdateImage() = 0; DisplayMode display_mode() const { return display_mode_; } const base::string16& message_text() const { return message_text_; } gfx::ImageSkia icon_image(); private: void DoRecognizingAnimationStep(); void DoWarmingUpAnimationStep(); void SetImage(const gfx::ImageSkia& image); void DrawVolumeOverlay(SkCanvas* canvas, const gfx::ImageSkia& image_skia, float volume); // Task factory used for animation timer. base::WeakPtrFactory<SpeechRecognitionBubbleBase> weak_factory_; int animation_step_; // Current index/step of the animation. DisplayMode display_mode_; base::string16 message_text_; // Text displayed in DISPLAY_MODE_MESSAGE // The current microphone image with volume level indication. scoped_ptr<SkBitmap> mic_image_; // A temporary buffer image used in creating the above mic image. scoped_ptr<SkBitmap> buffer_image_; // 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. float scale_; DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionBubbleBase); }; // This typedef is to workaround the issue with certain versions of // Visual Studio where it gets confused between multiple Delegate // classes and gives a C2500 error. (I saw this error on the try bots - // the workaround was not needed for my machine). typedef SpeechRecognitionBubble::Delegate SpeechRecognitionBubbleDelegate; #endif // CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_H_