// 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_ #pragma once #include #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, 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 session_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 session_id) = 0; protected: virtual ~Delegate() {} }; explicit SpeechRecognitionBubbleController(Delegate* delegate); // 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 session_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 session_id); // Indicates to the user that audio recording is in progress. This also makes // the bubble visible if not already visible. void SetBubbleRecordingMode(int session_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 session_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 session_id, const string16& text); // Updates the current captured audio volume displayed on screen. void SetBubbleInputVolume(int session_id, float volume, float noise_volume); void CloseBubble(int session_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: friend class base::RefCountedThreadSafe; // 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 }; virtual ~SpeechRecognitionBubbleController(); void InvokeDelegateButtonClicked(int session_id, SpeechRecognitionBubble::Button button); void InvokeDelegateFocusChanged(int session_id); void ProcessRequestInUiThread(int session_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 WebContents if this was the first bubble for the tab. Similarly if the // bubble was being removed, this method unregisters from WebContents if this // was the last bubble associated with that tab. void UpdateTabContentsSubscription(int session_id, ManageSubscriptionAction action); // Only accessed in the IO thread. Delegate* delegate_; // *** The following are accessed only in the UI thread. // The session id for currently visible bubble (since only one bubble is // visible at any time). int current_bubble_session_id_; // Map of session-ids to bubble objects. The bubbles are weak pointers owned // by this object and get destroyed by |CloseBubble|. typedef std::map BubbleSessionIdMap; BubbleSessionIdMap bubbles_; scoped_ptr 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_