summaryrefslogtreecommitdiffstats
path: root/chrome/browser/speech/speech_recognition_bubble_controller.h
blob: 735b9dd45b377f2fe5125848114d6d4103a6120b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// 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_CONTROLLER_H_
#define CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_CONTROLLER_H_

#include <map>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/speech/speech_recognition_bubble.h"
#include "content/public/browser/notification_observer.h"

namespace gfx {
class Rect;
}

namespace content {
class NotificationRegistrar;
}

namespace speech {

// This class handles the speech recognition popup UI on behalf of
// SpeechRecognitionManager, which invokes methods in the IO thread, processing
// those requests in the UI thread. There could be multiple bubble objects alive
// at the same time but only one of them is visible to the user. User actions on
// that bubble are reported to the delegate.
class SpeechRecognitionBubbleController
    : public base::RefCountedThreadSafe<SpeechRecognitionBubbleController>,
      public SpeechRecognitionBubbleDelegate,
      public content::NotificationObserver {
 public:
  // All methods of this delegate are called in the IO thread.
  class Delegate {
   public:
    // Invoked when the user clicks on a button in the speech recognition UI.
    virtual void InfoBubbleButtonClicked(
        int caller_id, SpeechRecognitionBubble::Button button) = 0;

    // Invoked when the user clicks outside the speech recognition info bubble
    // causing it to close and input focus to change.
    virtual void InfoBubbleFocusChanged(int caller_id) = 0;

   protected:
    virtual ~Delegate() {}
  };

  explicit SpeechRecognitionBubbleController(Delegate* delegate);
  virtual ~SpeechRecognitionBubbleController();

  // Creates a new speech recognition UI bubble. One of the SetXxxx methods
  // below need to be called to specify what to display.
  void CreateBubble(int caller_id,
                    int render_process_id,
                    int render_view_id,
                    const gfx::Rect& element_rect);

  // Indicates to the user that audio hardware is warming up. This also makes
  // the bubble visible if not already visible.
  void SetBubbleWarmUpMode(int caller_id);

  // Indicates to the user that audio recording is in progress. This also makes
  // the bubble visible if not already visible.
  void SetBubbleRecordingMode(int caller_id);

  // Indicates to the user that recognition is in progress. If the bubble is
  // hidden, |Show| must be called to make it appear on screen.
  void SetBubbleRecognizingMode(int caller_id);

  // 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.
  void SetBubbleMessage(int caller_id, const string16& text);

  // Updates the current captured audio volume displayed on screen.
  void SetBubbleInputVolume(int caller_id, float volume, float noise_volume);

  void CloseBubble(int caller_id);

  // SpeechRecognitionBubble::Delegate methods.
  virtual void InfoBubbleButtonClicked(
      SpeechRecognitionBubble::Button button) OVERRIDE;
  virtual void InfoBubbleFocusChanged() OVERRIDE;

  // content::NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

 private:
  // The various calls received by this object and handled in the UI thread.
  enum RequestType {
    REQUEST_SET_WARM_UP_MODE,
    REQUEST_SET_RECORDING_MODE,
    REQUEST_SET_RECOGNIZING_MODE,
    REQUEST_SET_MESSAGE,
    REQUEST_SET_INPUT_VOLUME,
    REQUEST_CLOSE,
  };

  enum ManageSubscriptionAction {
    BUBBLE_ADDED,
    BUBBLE_REMOVED
  };

  void InvokeDelegateButtonClicked(int caller_id,
                                   SpeechRecognitionBubble::Button button);
  void InvokeDelegateFocusChanged(int caller_id);
  void ProcessRequestInUiThread(int caller_id,
                                RequestType type,
                                const string16& text,
                                float volume,
                                float noise_volume);

  // Called whenever a bubble was added to or removed from the list. If the
  // bubble was being added, this method registers for close notifications with
  // the TabContents if this was the first bubble for the tab. Similarly if the
  // bubble was being removed, this method unregisters from TabContents if this
  // was the last bubble associated with that tab.
  void UpdateTabContentsSubscription(int caller_id,
                                     ManageSubscriptionAction action);

  // Only accessed in the IO thread.
  Delegate* delegate_;

  // *** The following are accessed only in the UI thread.

  // The caller id for currently visible bubble (since only one bubble is
  // visible at any time).
  int current_bubble_caller_id_;

  // Map of caller-ids to bubble objects. The bubbles are weak pointers owned by
  // this object and get destroyed by |CloseBubble|.
  typedef std::map<int, SpeechRecognitionBubble*> BubbleCallerIdMap;
  BubbleCallerIdMap bubbles_;

  scoped_ptr<content::NotificationRegistrar> registrar_;
};

// 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 SpeechRecognitionBubbleController::Delegate
    SpeechRecognitionBubbleControllerDelegate;

}  // namespace speech

#endif  // CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_CONTROLLER_H_