• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~Delegate()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)
set_factory(FactoryMethod factory)77   static void set_factory(FactoryMethod factory) { factory_ = factory; }
78 #endif
79 
~SpeechInputBubble()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 
display_mode()150   DisplayMode display_mode() {
151     return display_mode_;
152   }
153 
message_text()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