Add support for x-webkit-speech (issue #758).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1132 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
920ee60499
commit
63f6b6b09a
2
cef.gyp
2
cef.gyp
|
@ -894,6 +894,8 @@
|
|||
'libcef/browser/scheme_impl.cc',
|
||||
'libcef/browser/scheme_registration.cc',
|
||||
'libcef/browser/scheme_registration.h',
|
||||
'libcef/browser/speech_recognition_manager_delegate.cc',
|
||||
'libcef/browser/speech_recognition_manager_delegate.h',
|
||||
'libcef/browser/stream_impl.cc',
|
||||
'libcef/browser/stream_impl.h',
|
||||
'libcef/browser/trace_impl.cc',
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
#include "libcef/browser/download_manager_delegate.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/url_request_context_getter.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
|
@ -160,14 +162,19 @@ class CefSpeechRecognitionPreferences
|
|||
: public content::SpeechRecognitionPreferences {
|
||||
public:
|
||||
CefSpeechRecognitionPreferences() {
|
||||
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
|
||||
filter_profanities_ =
|
||||
command_line.HasSwitch(switches::kEnableProfanityFilter);
|
||||
}
|
||||
|
||||
// Overridden from SpeechRecognitionPreferences:
|
||||
virtual bool FilterProfanities() const OVERRIDE {
|
||||
return false;
|
||||
return filter_profanities_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool filter_profanities_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefSpeechRecognitionPreferences);
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
||||
#include "libcef/browser/resource_dispatcher_host_delegate.h"
|
||||
#include "libcef/browser/speech_recognition_manager_delegate.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/web_plugin_impl.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
|
@ -435,6 +436,7 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches(
|
|||
// any associated values) if present in the browser command line.
|
||||
static const char* const kSwitchNames[] = {
|
||||
switches::kContextSafetyImplementation,
|
||||
switches::kEnableSpeechInput,
|
||||
switches::kProductVersion,
|
||||
switches::kUncaughtExceptionStackSize,
|
||||
};
|
||||
|
@ -464,6 +466,17 @@ content::MediaObserver* CefContentBrowserClient::GetMediaObserver() {
|
|||
return CefMediaCaptureDevicesDispatcher::GetInstance();
|
||||
}
|
||||
|
||||
content::SpeechRecognitionManagerDelegate*
|
||||
CefContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
|
||||
#if defined(ENABLE_INPUT_SPEECH)
|
||||
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
|
||||
if (command_line.HasSwitch(switches::kEnableSpeechInput))
|
||||
return new CefSpeechRecognitionManagerDelegate();
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
content::AccessTokenStore* CefContentBrowserClient::CreateAccessTokenStore() {
|
||||
return new CefAccessTokenStore;
|
||||
}
|
||||
|
|
|
@ -97,6 +97,8 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
|||
virtual content::QuotaPermissionContext*
|
||||
CreateQuotaPermissionContext() OVERRIDE;
|
||||
virtual content::MediaObserver* GetMediaObserver() OVERRIDE;
|
||||
virtual content::SpeechRecognitionManagerDelegate*
|
||||
GetSpeechRecognitionManagerDelegate() OVERRIDE;
|
||||
virtual content::AccessTokenStore* CreateAccessTokenStore() OVERRIDE;
|
||||
virtual bool CanCreateWindow(const GURL& opener_url,
|
||||
const GURL& origin,
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
// 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.
|
||||
|
||||
#include "libcef/browser/speech_recognition_manager_delegate.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/notification_observer.h"
|
||||
#include "content/public/browser/notification_registrar.h"
|
||||
#include "content/public/browser/notification_source.h"
|
||||
#include "content/public/browser/notification_types.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/speech_recognition_manager.h"
|
||||
#include "content/public/browser/speech_recognition_session_context.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/speech_recognition_error.h"
|
||||
#include "content/public/common/speech_recognition_result.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::SpeechRecognitionManager;
|
||||
using content::WebContents;
|
||||
|
||||
// Simple utility to get notified when a WebContents is closed or crashes.
|
||||
// Both the callback site and the callback thread are passed by the caller in
|
||||
// the constructor. There is no restriction on the constructor, however this
|
||||
// class must be destroyed on the UI thread, due to the NotificationRegistrar
|
||||
// dependency.
|
||||
class CefSpeechRecognitionManagerDelegate::WebContentsWatcher
|
||||
: public base::RefCountedThreadSafe<WebContentsWatcher>,
|
||||
public content::NotificationObserver {
|
||||
public:
|
||||
typedef base::Callback<void(int render_process_id, int render_view_id)>
|
||||
WebContentsClosedCallback;
|
||||
|
||||
WebContentsWatcher(WebContentsClosedCallback web_contents_closed_callback,
|
||||
BrowserThread::ID callback_thread)
|
||||
: web_contents_closed_callback_(web_contents_closed_callback),
|
||||
callback_thread_(callback_thread) {
|
||||
}
|
||||
|
||||
// Starts monitoring the WebContents corresponding to the given
|
||||
// |render_process_id|, |render_view_id| pair, invoking
|
||||
// |web_contents_closed_callback_| if closed/unloaded.
|
||||
void Watch(int render_process_id, int render_view_id) {
|
||||
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
|
||||
&WebContentsWatcher::Watch, this, render_process_id, render_view_id));
|
||||
return;
|
||||
}
|
||||
|
||||
WebContents* web_contents = NULL;
|
||||
content::RenderViewHost* render_view_host =
|
||||
content::RenderViewHost::FromID(render_process_id, render_view_id);
|
||||
if (render_view_host)
|
||||
web_contents = WebContents::FromRenderViewHost(render_view_host);
|
||||
DCHECK(web_contents);
|
||||
|
||||
// Avoid multiple registrations on |registrar_| for the same |web_contents|.
|
||||
if (registered_web_contents_.find(web_contents) !=
|
||||
registered_web_contents_.end()) {
|
||||
return;
|
||||
}
|
||||
registered_web_contents_.insert(web_contents);
|
||||
|
||||
// Lazy initialize the registrar.
|
||||
if (!registrar_.get())
|
||||
registrar_.reset(new content::NotificationRegistrar());
|
||||
|
||||
registrar_->Add(this,
|
||||
content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
|
||||
content::Source<WebContents>(web_contents));
|
||||
}
|
||||
|
||||
// content::NotificationObserver implementation.
|
||||
virtual void Observe(int type,
|
||||
const content::NotificationSource& source,
|
||||
const content::NotificationDetails& details) OVERRIDE {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, type);
|
||||
|
||||
WebContents* web_contents = content::Source<WebContents>(source).ptr();
|
||||
int render_process_id = web_contents->GetRenderProcessHost()->GetID();
|
||||
int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
|
||||
|
||||
registrar_->Remove(this,
|
||||
content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
|
||||
content::Source<WebContents>(web_contents));
|
||||
registered_web_contents_.erase(web_contents);
|
||||
|
||||
BrowserThread::PostTask(callback_thread_, FROM_HERE, base::Bind(
|
||||
web_contents_closed_callback_, render_process_id, render_view_id));
|
||||
}
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<WebContentsWatcher>;
|
||||
|
||||
virtual ~WebContentsWatcher() {
|
||||
// Must be destroyed on the UI thread due to |registrar_| non thread-safety.
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
}
|
||||
|
||||
// Lazy-initialized and used on the UI thread to handle web contents
|
||||
// notifications (tab closing).
|
||||
scoped_ptr<content::NotificationRegistrar> registrar_;
|
||||
|
||||
// Keeps track of which WebContent(s) have been registered, in order to avoid
|
||||
// double registrations on |registrar_|
|
||||
std::set<content::WebContents*> registered_web_contents_;
|
||||
|
||||
// Callback used to notify, on the thread specified by |callback_thread_| the
|
||||
// closure of a registered tab.
|
||||
WebContentsClosedCallback web_contents_closed_callback_;
|
||||
content::BrowserThread::ID callback_thread_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContentsWatcher);
|
||||
};
|
||||
|
||||
CefSpeechRecognitionManagerDelegate
|
||||
::CefSpeechRecognitionManagerDelegate() {
|
||||
}
|
||||
|
||||
CefSpeechRecognitionManagerDelegate
|
||||
::~CefSpeechRecognitionManagerDelegate() {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::WebContentsClosedCallback(
|
||||
int render_process_id, int render_view_id) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||
|
||||
SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance();
|
||||
// |manager| becomes NULL if a browser shutdown happens between the post of
|
||||
// this task (from the UI thread) and this call (on the IO thread). In this
|
||||
// case we just return.
|
||||
if (!manager)
|
||||
return;
|
||||
|
||||
manager->AbortAllSessionsForRenderView(render_process_id, render_view_id);
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnRecognitionStart(
|
||||
int session_id) {
|
||||
const content::SpeechRecognitionSessionContext& context =
|
||||
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
|
||||
|
||||
// Register callback to auto abort session on tab closure.
|
||||
// |web_contents_watcher_| is lazyly istantiated on the first call.
|
||||
if (!web_contents_watcher_.get()) {
|
||||
web_contents_watcher_ = new WebContentsWatcher(
|
||||
base::Bind(
|
||||
&CefSpeechRecognitionManagerDelegate::WebContentsClosedCallback,
|
||||
base::Unretained(this)),
|
||||
BrowserThread::IO);
|
||||
}
|
||||
web_contents_watcher_->Watch(context.render_process_id,
|
||||
context.render_view_id);
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete(
|
||||
int session_id) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnRecognitionResults(
|
||||
int session_id, const content::SpeechRecognitionResults& result) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnRecognitionError(
|
||||
int session_id, const content::SpeechRecognitionError& error) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
|
||||
int session_id, float volume, float noise_volume) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) {
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::GetDiagnosticInformation(
|
||||
bool* can_report_metrics,
|
||||
std::string* hardware_info) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||
}
|
||||
|
||||
void CefSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed(
|
||||
int session_id,
|
||||
base::Callback<void(bool ask_user, bool is_allowed)> callback) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||
|
||||
const content::SpeechRecognitionSessionContext& context =
|
||||
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
|
||||
|
||||
// Make sure that initiators properly set the |render_process_id| field.
|
||||
DCHECK_NE(context.render_process_id, 0);
|
||||
|
||||
callback.Run(false, true);
|
||||
}
|
||||
|
||||
content::SpeechRecognitionEventListener*
|
||||
CefSpeechRecognitionManagerDelegate::GetEventListener() {
|
||||
return this;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// 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 CEF_LIBCEF_BROWSER_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
|
||||
#define CEF_LIBCEF_BROWSER_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "content/public/browser/speech_recognition_event_listener.h"
|
||||
#include "content/public/browser/speech_recognition_manager_delegate.h"
|
||||
|
||||
|
||||
// This is CEF's implementation of the SpeechRecognitionManagerDelegate
|
||||
// interface. Based on chrome/browser/speech/
|
||||
// chrome_speech_recognition_manager_delegate.[cc|h]
|
||||
class CefSpeechRecognitionManagerDelegate
|
||||
: NON_EXPORTED_BASE(public content::SpeechRecognitionManagerDelegate),
|
||||
public content::SpeechRecognitionEventListener {
|
||||
public:
|
||||
CefSpeechRecognitionManagerDelegate();
|
||||
virtual ~CefSpeechRecognitionManagerDelegate();
|
||||
|
||||
protected:
|
||||
// SpeechRecognitionEventListener methods.
|
||||
virtual void OnRecognitionStart(int session_id) OVERRIDE;
|
||||
virtual void OnAudioStart(int session_id) OVERRIDE;
|
||||
virtual void OnEnvironmentEstimationComplete(int session_id) OVERRIDE;
|
||||
virtual void OnSoundStart(int session_id) OVERRIDE;
|
||||
virtual void OnSoundEnd(int session_id) OVERRIDE;
|
||||
virtual void OnAudioEnd(int session_id) OVERRIDE;
|
||||
virtual void OnRecognitionEnd(int session_id) OVERRIDE;
|
||||
virtual void OnRecognitionResults(
|
||||
int session_id, const content::SpeechRecognitionResults& result) OVERRIDE;
|
||||
virtual void OnRecognitionError(
|
||||
int session_id, const content::SpeechRecognitionError& error) OVERRIDE;
|
||||
virtual void OnAudioLevelsChange(int session_id, float volume,
|
||||
float noise_volume) OVERRIDE;
|
||||
|
||||
// SpeechRecognitionManagerDelegate methods.
|
||||
virtual void GetDiagnosticInformation(bool* can_report_metrics,
|
||||
std::string* hardware_info) OVERRIDE;
|
||||
virtual void CheckRecognitionIsAllowed(
|
||||
int session_id,
|
||||
base::Callback<void(bool ask_user, bool is_allowed)> callback) OVERRIDE;
|
||||
virtual content::SpeechRecognitionEventListener* GetEventListener() OVERRIDE;
|
||||
|
||||
private:
|
||||
class WebContentsWatcher;
|
||||
|
||||
// Callback called by |web_contents_watcher_| on the IO thread to signal
|
||||
// web contents closure.
|
||||
void WebContentsClosedCallback(int render_process_id, int render_view_id);
|
||||
|
||||
scoped_refptr<WebContentsWatcher> web_contents_watcher_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefSpeechRecognitionManagerDelegate);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
|
|
@ -89,4 +89,10 @@ const char kPersistSessionCookies[] = "persist-session-cookies";
|
|||
// Enable media (WebRTC audio/video) streaming.
|
||||
const char kEnableMediaStream[] = "enable-media-stream";
|
||||
|
||||
// Enable speech input (x-webkit-speech).
|
||||
const char kEnableSpeechInput[] = "enable-speech-input";
|
||||
|
||||
// Enable the speech input profanity filter.
|
||||
const char kEnableProfanityFilter[] = "enable-profanity-filter";
|
||||
|
||||
} // namespace switches
|
||||
|
|
|
@ -40,6 +40,8 @@ extern const char kDisableAuthorAndUserStyles[];
|
|||
extern const char kDisableDeveloperTools[];
|
||||
extern const char kPersistSessionCookies[];
|
||||
extern const char kEnableMediaStream[];
|
||||
extern const char kEnableSpeechInput[];
|
||||
extern const char kEnableProfanityFilter[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
|
|
|
@ -272,12 +272,17 @@ void CefContentRendererClient::AddCustomScheme(
|
|||
}
|
||||
|
||||
void CefContentRendererClient::WebKitInitialized() {
|
||||
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
|
||||
|
||||
WebKit::WebRuntimeFeatures::enableMediaPlayer(
|
||||
media::IsMediaLibraryInitialized());
|
||||
|
||||
// TODO(cef): Enable these once the implementation supports it.
|
||||
WebKit::WebRuntimeFeatures::enableNotifications(false);
|
||||
|
||||
WebKit::WebRuntimeFeatures::enableSpeechInput(
|
||||
command_line.HasSwitch(switches::kEnableSpeechInput));
|
||||
|
||||
worker_script_observer_.reset(new CefWebWorkerScriptObserver());
|
||||
WebKit::WebWorkerInfo::addScriptObserver(worker_script_observer_.get());
|
||||
|
||||
|
@ -313,7 +318,6 @@ void CefContentRendererClient::WebKitInitialized() {
|
|||
}
|
||||
|
||||
// The number of stack trace frames to capture for uncaught exceptions.
|
||||
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
|
||||
if (command_line.HasSwitch(switches::kUncaughtExceptionStackSize)) {
|
||||
int uncaught_exception_stack_size = 0;
|
||||
base::StringToInt(
|
||||
|
|
Loading…
Reference in New Issue