1// Copyright (c) 2012 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#include "content/renderer/input_tag_speech_dispatcher.h" 6 7#include "base/strings/utf_string_conversions.h" 8#include "content/common/speech_recognition_messages.h" 9#include "content/renderer/render_view_impl.h" 10#include "third_party/WebKit/public/platform/WebSize.h" 11#include "third_party/WebKit/public/platform/WebString.h" 12#include "third_party/WebKit/public/web/WebDocument.h" 13#include "third_party/WebKit/public/web/WebElement.h" 14#include "third_party/WebKit/public/web/WebFrame.h" 15#include "third_party/WebKit/public/web/WebInputElement.h" 16#include "third_party/WebKit/public/web/WebNode.h" 17#include "third_party/WebKit/public/web/WebSecurityOrigin.h" 18#include "third_party/WebKit/public/web/WebSpeechInputListener.h" 19#include "third_party/WebKit/public/web/WebView.h" 20 21using WebKit::WebDocument; 22using WebKit::WebElement; 23using WebKit::WebFrame; 24using WebKit::WebInputElement; 25using WebKit::WebNode; 26using WebKit::WebView; 27 28namespace content { 29 30InputTagSpeechDispatcher::InputTagSpeechDispatcher( 31 RenderViewImpl* render_view, 32 WebKit::WebSpeechInputListener* listener) 33 : RenderViewObserver(render_view), 34 listener_(listener) { 35} 36 37bool InputTagSpeechDispatcher::OnMessageReceived( 38 const IPC::Message& message) { 39 bool handled = true; 40 IPC_BEGIN_MESSAGE_MAP(InputTagSpeechDispatcher, message) 41 IPC_MESSAGE_HANDLER(InputTagSpeechMsg_SetRecognitionResults, 42 OnSpeechRecognitionResults) 43 IPC_MESSAGE_HANDLER(InputTagSpeechMsg_RecordingComplete, 44 OnSpeechRecordingComplete) 45 IPC_MESSAGE_HANDLER(InputTagSpeechMsg_RecognitionComplete, 46 OnSpeechRecognitionComplete) 47 IPC_MESSAGE_HANDLER(InputTagSpeechMsg_ToggleSpeechInput, 48 OnSpeechRecognitionToggleSpeechInput) 49 IPC_MESSAGE_UNHANDLED(handled = false) 50 IPC_END_MESSAGE_MAP() 51 return handled; 52} 53 54bool InputTagSpeechDispatcher::startRecognition( 55 int request_id, 56 const WebKit::WebRect& element_rect, 57 const WebKit::WebString& language, 58 const WebKit::WebString& grammar, 59 const WebKit::WebSecurityOrigin& origin) { 60 DVLOG(1) << "InputTagSpeechDispatcher::startRecognition enter"; 61 62 InputTagSpeechHostMsg_StartRecognition_Params params; 63 params.grammar = UTF16ToUTF8(grammar); 64 params.language = UTF16ToUTF8(language); 65 params.origin_url = UTF16ToUTF8(origin.toString()); 66 params.render_view_id = routing_id(); 67 params.request_id = request_id; 68 params.element_rect = element_rect; 69 70 Send(new InputTagSpeechHostMsg_StartRecognition(params)); 71 DVLOG(1) << "InputTagSpeechDispatcher::startRecognition exit"; 72 return true; 73} 74 75void InputTagSpeechDispatcher::cancelRecognition(int request_id) { 76 DVLOG(1) << "InputTagSpeechDispatcher::cancelRecognition enter"; 77 Send(new InputTagSpeechHostMsg_CancelRecognition(routing_id(), request_id)); 78 DVLOG(1) << "InputTagSpeechDispatcher::cancelRecognition exit"; 79} 80 81void InputTagSpeechDispatcher::stopRecording(int request_id) { 82 DVLOG(1) << "InputTagSpeechDispatcher::stopRecording enter"; 83 Send(new InputTagSpeechHostMsg_StopRecording(routing_id(), 84 request_id)); 85 DVLOG(1) << "InputTagSpeechDispatcher::stopRecording exit"; 86} 87 88void InputTagSpeechDispatcher::OnSpeechRecognitionResults( 89 int request_id, 90 const SpeechRecognitionResults& results) { 91 DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecognitionResults enter"; 92 DCHECK_EQ(results.size(), 1U); 93 94 const SpeechRecognitionResult& result = results[0]; 95 WebKit::WebSpeechInputResultArray webkit_result(result.hypotheses.size()); 96 for (size_t i = 0; i < result.hypotheses.size(); ++i) { 97 webkit_result[i].assign(result.hypotheses[i].utterance, 98 result.hypotheses[i].confidence); 99 } 100 listener_->setRecognitionResult(request_id, webkit_result); 101 102 DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecognitionResults exit"; 103} 104 105void InputTagSpeechDispatcher::OnSpeechRecordingComplete(int request_id) { 106 DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecordingComplete enter"; 107 listener_->didCompleteRecording(request_id); 108 DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecordingComplete exit"; 109} 110 111void InputTagSpeechDispatcher::OnSpeechRecognitionComplete(int request_id) { 112 DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecognitionComplete enter"; 113 listener_->didCompleteRecognition(request_id); 114 DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecognitionComplete exit"; 115} 116 117void InputTagSpeechDispatcher::OnSpeechRecognitionToggleSpeechInput() { 118 DVLOG(1) <<"InputTagSpeechDispatcher::OnSpeechRecognitionToggleSpeechInput"; 119 120 WebView* web_view = render_view()->GetWebView(); 121 122 WebFrame* frame = web_view->mainFrame(); 123 if (!frame) 124 return; 125 126 WebDocument document = frame->document(); 127 if (document.isNull()) 128 return; 129 130 WebNode focused_node = document.focusedNode(); 131 if (focused_node.isNull() || !focused_node.isElementNode()) 132 return; 133 134 WebKit::WebElement element = focused_node.to<WebKit::WebElement>(); 135 WebKit::WebInputElement* input_element = WebKit::toWebInputElement(&element); 136 if (!input_element) 137 return; 138 if (!input_element->isSpeechInputEnabled()) 139 return; 140 141 if (input_element->getSpeechInputState() == WebInputElement::Idle) { 142 input_element->startSpeechInput(); 143 } else { 144 input_element->stopSpeechInput(); 145 } 146} 147 148} // namespace content 149