Home | History | Annotate | Download | only in speech
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_SPEECH_SPEECH_INPUT_BUBBLE_H_
      6 #define CHROME_BROWSER_SPEECH_SPEECH_INPUT_BUBBLE_H_
      7 #pragma once
      8 
      9 #include <vector>
     10 
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/string16.h"
     13 #include "base/task.h"
     14 
     15 namespace gfx {
     16 class Canvas;
     17 class Rect;
     18 }
     19 class SkBitmap;
     20 class SkCanvas;
     21 class TabContents;
     22 
     23 // SpeechInputBubble displays a popup info bubble during speech recognition,
     24 // points to the html element which requested speech input and shows recognition
     25 // progress events. The popup is closed by the user clicking anywhere outside
     26 // the popup window, or by the caller destroying this object.
     27 class SpeechInputBubble {
     28  public:
     29   // The various buttons which may be part of the bubble.
     30   enum Button {
     31     BUTTON_TRY_AGAIN,
     32     BUTTON_CANCEL
     33   };
     34 
     35   // Informs listeners of user actions in the bubble.
     36   class Delegate {
     37    public:
     38     // Invoked when the user selects a button in the info bubble. The InfoBubble
     39     // is still active and the caller should close it if necessary.
     40     virtual void InfoBubbleButtonClicked(Button button) = 0;
     41 
     42     // Invoked when the user clicks outside the InfoBubble causing it to close.
     43     // The InfoBubble window is no longer visible on screen and the caller can
     44     // free the InfoBubble instance. This callback is not issued if the bubble
     45     // got closed because the object was destroyed by the caller.
     46     virtual void InfoBubbleFocusChanged() = 0;
     47 
     48    protected:
     49     virtual ~Delegate() {
     50     }
     51   };
     52 
     53   // Factory method to create new instances.
     54   // Creates the bubble, call |Show| to display it on screen.
     55   // |tab_contents| is the TabContents hosting the page.
     56   // |element_rect| is the display bounds of the html element requesting speech
     57   // input (in page coordinates).
     58   static SpeechInputBubble* Create(TabContents* tab_contents,
     59                                    Delegate* delegate,
     60                                    const gfx::Rect& element_rect);
     61 
     62   // This is implemented by platform specific code to create the underlying
     63   // bubble window. Not to be called directly by users of this class.
     64   static SpeechInputBubble* CreateNativeBubble(TabContents* tab_contents,
     65                                                Delegate* delegate,
     66                                                const gfx::Rect& element_rect);
     67 
     68   // |Create| uses the currently registered FactoryMethod to create the
     69   // SpeechInputBubble instances. FactoryMethod is intended for testing.
     70   typedef SpeechInputBubble* (*FactoryMethod)(TabContents*,
     71                                               Delegate*,
     72                                               const gfx::Rect&);
     73   // Sets the factory used by the static method Create. SpeechInputBubble does
     74   // not take ownership of |factory|. A value of NULL results in a
     75   // SpeechInputBubble being created directly.
     76 #if defined(UNIT_TEST)
     77   static void set_factory(FactoryMethod factory) { factory_ = factory; }
     78 #endif
     79 
     80   virtual ~SpeechInputBubble() {}
     81 
     82   // Indicates to the user that audio hardware is initializing. If the bubble is
     83   // hidden, |Show| must be called to make it appear on screen.
     84   virtual void SetWarmUpMode() = 0;
     85 
     86   // Indicates to the user that audio recording is in progress. If the bubble is
     87   // hidden, |Show| must be called to make it appear on screen.
     88   virtual void SetRecordingMode() = 0;
     89 
     90   // Indicates to the user that recognition is in progress. If the bubble is
     91   // hidden, |Show| must be called to make it appear on screen.
     92   virtual void SetRecognizingMode() = 0;
     93 
     94   // Displays the given string with the 'Try again' and 'Cancel' buttons. If the
     95   // bubble is hidden, |Show| must be called to make it appear on screen.
     96   virtual void SetMessage(const string16& text) = 0;
     97 
     98   // Brings up the bubble on screen.
     99   virtual void Show() = 0;
    100 
    101   // Hides the info bubble, resulting in a call to
    102   // |Delegate::InfoBubbleFocusChanged| as well.
    103   virtual void Hide() = 0;
    104 
    105   // Updates and draws the current captured audio volume displayed on screen.
    106   virtual void SetInputVolume(float volume, float noise_volume) = 0;
    107 
    108   // Returns the TabContents for which this bubble gets displayed.
    109   virtual TabContents* tab_contents() = 0;
    110 
    111   // The horizontal distance between the start of the html widget and the speech
    112   // bubble's arrow.
    113   static const int kBubbleTargetOffsetX;
    114 
    115  private:
    116   static FactoryMethod factory_;
    117 };
    118 
    119 // Base class for the platform specific bubble implementations, this contains
    120 // the platform independent code for SpeechInputBubble.
    121 class SpeechInputBubbleBase : public SpeechInputBubble {
    122  public:
    123   // The current display mode of the bubble, useful only for the platform
    124   // specific implementation.
    125   enum DisplayMode {
    126     DISPLAY_MODE_WARM_UP,
    127     DISPLAY_MODE_RECORDING,
    128     DISPLAY_MODE_RECOGNIZING,
    129     DISPLAY_MODE_MESSAGE
    130   };
    131 
    132   explicit SpeechInputBubbleBase(TabContents* tab_contents);
    133   virtual ~SpeechInputBubbleBase();
    134 
    135   // SpeechInputBubble methods
    136   virtual void SetWarmUpMode();
    137   virtual void SetRecordingMode();
    138   virtual void SetRecognizingMode();
    139   virtual void SetMessage(const string16& text);
    140   virtual void SetInputVolume(float volume, float noise_volume);
    141   virtual TabContents* tab_contents();
    142 
    143  protected:
    144   // Updates the platform specific UI layout for the current display mode.
    145   virtual void UpdateLayout() = 0;
    146 
    147   // Overridden by subclasses to copy |icon_image()| to the screen.
    148   virtual void UpdateImage() = 0;
    149 
    150   DisplayMode display_mode() {
    151     return display_mode_;
    152   }
    153 
    154   string16 message_text() {
    155     return message_text_;
    156   }
    157 
    158   SkBitmap icon_image();
    159 
    160  private:
    161   void DoRecognizingAnimationStep();
    162   void DoWarmingUpAnimationStep();
    163   void SetImage(const SkBitmap& image);
    164 
    165   void DrawVolumeOverlay(SkCanvas* canvas,
    166                          const SkBitmap& bitmap,
    167                          float volume);
    168 
    169   // Task factory used for animation timer.
    170   ScopedRunnableMethodFactory<SpeechInputBubbleBase> task_factory_;
    171   int animation_step_;  // Current index/step of the animation.
    172   std::vector<SkBitmap> animation_frames_;
    173   std::vector<SkBitmap> warming_up_frames_;
    174 
    175   DisplayMode display_mode_;
    176   string16 message_text_;  // Text displayed in DISPLAY_MODE_MESSAGE
    177   // The current microphone image with volume level indication.
    178   scoped_ptr<SkBitmap> mic_image_;
    179   // A temporary buffer image used in creating the above mic image.
    180   scoped_ptr<SkBitmap> buffer_image_;
    181   // TabContents in which this this bubble gets displayed.
    182   TabContents* tab_contents_;
    183   // The current image displayed in the bubble's icon widget.
    184   scoped_ptr<SkBitmap> icon_image_;
    185 };
    186 
    187 // This typedef is to workaround the issue with certain versions of
    188 // Visual Studio where it gets confused between multiple Delegate
    189 // classes and gives a C2500 error. (I saw this error on the try bots -
    190 // the workaround was not needed for my machine).
    191 typedef SpeechInputBubble::Delegate SpeechInputBubbleDelegate;
    192 
    193 #endif  // CHROME_BROWSER_SPEECH_SPEECH_INPUT_BUBBLE_H_
    194