OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/memory/singleton.h" | 6 #include "base/memory/singleton.h" |
7 #include "base/memory/weak_ptr.h" | 7 #include "base/memory/weak_ptr.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "chrome/browser/chromeos/cros/cros_library.h" | 10 #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" |
11 #include "chrome/browser/chromeos/cros/speech_synthesis_library.h" | 11 #include "chrome/browser/chromeos/dbus/speech_synthesizer_client.h" |
12 #include "chrome/browser/extensions/extension_tts_api_controller.h" | 12 #include "chrome/browser/extensions/extension_tts_api_controller.h" |
13 #include "chrome/browser/extensions/extension_tts_api_platform.h" | 13 #include "chrome/browser/extensions/extension_tts_api_platform.h" |
14 | 14 |
15 using base::DoubleToString; | 15 using base::DoubleToString; |
16 | 16 |
17 namespace { | 17 namespace { |
18 const char kCrosLibraryNotLoadedError[] = "Cros shared library not loaded."; | |
19 const int kSpeechCheckDelayIntervalMs = 100; | 18 const int kSpeechCheckDelayIntervalMs = 100; |
20 }; | 19 }; |
21 | 20 |
22 class ExtensionTtsPlatformImplChromeOs : public ExtensionTtsPlatformImpl { | 21 class ExtensionTtsPlatformImplChromeOs : public ExtensionTtsPlatformImpl { |
23 public: | 22 public: |
24 virtual bool PlatformImplAvailable() { | 23 virtual bool PlatformImplAvailable() { |
25 return true; | 24 return true; |
26 } | 25 } |
27 | 26 |
28 virtual bool Speak( | 27 virtual bool Speak( |
29 int utterance_id, | 28 int utterance_id, |
30 const std::string& utterance, | 29 const std::string& utterance, |
31 const std::string& lang, | 30 const std::string& lang, |
32 const UtteranceContinuousParameters& params); | 31 const UtteranceContinuousParameters& params); |
33 | 32 |
34 virtual bool StopSpeaking(); | 33 virtual bool StopSpeaking(); |
35 | 34 |
36 virtual bool SendsEvent(TtsEventType event_type); | 35 virtual bool SendsEvent(TtsEventType event_type); |
37 | 36 |
38 // Get the single instance of this class. | 37 // Get the single instance of this class. |
39 static ExtensionTtsPlatformImplChromeOs* GetInstance(); | 38 static ExtensionTtsPlatformImplChromeOs* GetInstance(); |
40 | 39 |
41 private: | 40 private: |
42 ExtensionTtsPlatformImplChromeOs() | 41 ExtensionTtsPlatformImplChromeOs() |
43 : ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) {} | 42 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {} |
44 virtual ~ExtensionTtsPlatformImplChromeOs() {} | 43 virtual ~ExtensionTtsPlatformImplChromeOs() {} |
45 | 44 |
46 void PollUntilSpeechFinishes(int utterance_id); | 45 void PollUntilSpeechFinishes(int utterance_id); |
| 46 void ContinuePollingIfSpeechIsNotFinished(int utterance_id, bool result); |
47 | 47 |
48 void AppendSpeakOption(std::string key, | 48 void AppendSpeakOption(std::string key, |
49 std::string value, | 49 std::string value, |
50 std::string* options); | 50 std::string* options); |
51 | 51 |
52 int utterance_id_; | 52 int utterance_id_; |
53 int utterance_length_; | 53 int utterance_length_; |
54 base::WeakPtrFactory<ExtensionTtsPlatformImplChromeOs> ptr_factory_; | 54 base::WeakPtrFactory<ExtensionTtsPlatformImplChromeOs> weak_ptr_factory_; |
55 | 55 |
56 friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplChromeOs>; | 56 friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplChromeOs>; |
57 | 57 |
58 DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplChromeOs); | 58 DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplChromeOs); |
59 }; | 59 }; |
60 | 60 |
61 // static | 61 // static |
62 ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() { | 62 ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() { |
63 return ExtensionTtsPlatformImplChromeOs::GetInstance(); | 63 return ExtensionTtsPlatformImplChromeOs::GetInstance(); |
64 } | 64 } |
65 | 65 |
66 bool ExtensionTtsPlatformImplChromeOs::Speak( | 66 bool ExtensionTtsPlatformImplChromeOs::Speak( |
67 int utterance_id, | 67 int utterance_id, |
68 const std::string& utterance, | 68 const std::string& utterance, |
69 const std::string& lang, | 69 const std::string& lang, |
70 const UtteranceContinuousParameters& params) { | 70 const UtteranceContinuousParameters& params) { |
71 chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); | |
72 if (!cros_library->EnsureLoaded()) { | |
73 set_error(kCrosLibraryNotLoadedError); | |
74 return false; | |
75 } | |
76 | |
77 utterance_id_ = utterance_id; | 71 utterance_id_ = utterance_id; |
78 utterance_length_ = utterance.size(); | 72 utterance_length_ = utterance.size(); |
79 | 73 |
80 std::string options; | 74 std::string options; |
81 | 75 |
82 if (!lang.empty()) { | 76 if (!lang.empty()) { |
83 AppendSpeakOption( | 77 AppendSpeakOption( |
84 chromeos::SpeechSynthesisLibrary::kSpeechPropertyLocale, | 78 chromeos::SpeechSynthesizerClient::kSpeechPropertyLocale, |
85 lang, | 79 lang, |
86 &options); | 80 &options); |
87 } | 81 } |
88 | 82 |
89 if (params.rate >= 0.0) { | 83 if (params.rate >= 0.0) { |
90 AppendSpeakOption( | 84 AppendSpeakOption( |
91 chromeos::SpeechSynthesisLibrary::kSpeechPropertyRate, | 85 chromeos::SpeechSynthesizerClient::kSpeechPropertyRate, |
92 DoubleToString(params.rate), | 86 DoubleToString(params.rate), |
93 &options); | 87 &options); |
94 } | 88 } |
95 | 89 |
96 if (params.pitch >= 0.0) { | 90 if (params.pitch >= 0.0) { |
97 // The TTS service allows a range of 0 to 2 for speech pitch. | 91 // The TTS service allows a range of 0 to 2 for speech pitch. |
98 AppendSpeakOption( | 92 AppendSpeakOption( |
99 chromeos::SpeechSynthesisLibrary::kSpeechPropertyPitch, | 93 chromeos::SpeechSynthesizerClient::kSpeechPropertyPitch, |
100 DoubleToString(params.pitch), | 94 DoubleToString(params.pitch), |
101 &options); | 95 &options); |
102 } | 96 } |
103 | 97 |
104 if (params.volume >= 0.0) { | 98 if (params.volume >= 0.0) { |
105 // The Chrome OS TTS service allows a range of 0 to 5 for speech volume, | 99 // The Chrome OS TTS service allows a range of 0 to 5 for speech volume, |
106 // but 5 clips, so map to a range of 0...4. | 100 // but 5 clips, so map to a range of 0...4. |
107 AppendSpeakOption( | 101 AppendSpeakOption( |
108 chromeos::SpeechSynthesisLibrary::kSpeechPropertyVolume, | 102 chromeos::SpeechSynthesizerClient::kSpeechPropertyVolume, |
109 DoubleToString(params.volume * 4), | 103 DoubleToString(params.volume * 4), |
110 &options); | 104 &options); |
111 } | 105 } |
112 | 106 |
113 if (!options.empty()) { | 107 chromeos::SpeechSynthesizerClient* speech_synthesizer_client = |
114 cros_library->GetSpeechSynthesisLibrary()->SetSpeakProperties( | 108 chromeos::DBusThreadManager::Get()->speech_synthesizer_client(); |
115 options.c_str()); | |
116 } | |
117 | 109 |
118 bool result = | 110 if (!options.empty()) |
119 cros_library->GetSpeechSynthesisLibrary()->Speak(utterance.c_str()); | 111 speech_synthesizer_client->SetSpeakProperties(options); |
120 | 112 |
121 if (result) { | 113 speech_synthesizer_client->Speak(utterance); |
122 ExtensionTtsController* controller = ExtensionTtsController::GetInstance(); | 114 ExtensionTtsController* controller = ExtensionTtsController::GetInstance(); |
123 controller->OnTtsEvent(utterance_id_, TTS_EVENT_START, 0, std::string()); | 115 controller->OnTtsEvent(utterance_id_, TTS_EVENT_START, 0, std::string()); |
124 PollUntilSpeechFinishes(utterance_id_); | 116 PollUntilSpeechFinishes(utterance_id_); |
125 } | |
126 | 117 |
127 return result; | 118 return true; |
128 } | 119 } |
129 | 120 |
130 bool ExtensionTtsPlatformImplChromeOs::StopSpeaking() { | 121 bool ExtensionTtsPlatformImplChromeOs::StopSpeaking() { |
131 if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { | 122 chromeos::DBusThreadManager::Get()->speech_synthesizer_client()-> |
132 return chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> | 123 StopSpeaking(); |
133 StopSpeaking(); | 124 return true; |
134 } | |
135 | |
136 set_error(kCrosLibraryNotLoadedError); | |
137 return false; | |
138 } | 125 } |
139 | 126 |
140 bool ExtensionTtsPlatformImplChromeOs::SendsEvent(TtsEventType event_type) { | 127 bool ExtensionTtsPlatformImplChromeOs::SendsEvent(TtsEventType event_type) { |
141 return (event_type == TTS_EVENT_START || | 128 return (event_type == TTS_EVENT_START || |
142 event_type == TTS_EVENT_END || | 129 event_type == TTS_EVENT_END || |
143 event_type == TTS_EVENT_ERROR); | 130 event_type == TTS_EVENT_ERROR); |
144 } | 131 } |
145 | 132 |
146 void ExtensionTtsPlatformImplChromeOs::PollUntilSpeechFinishes( | 133 void ExtensionTtsPlatformImplChromeOs::PollUntilSpeechFinishes( |
147 int utterance_id) { | 134 int utterance_id) { |
148 if (utterance_id != utterance_id_) { | 135 if (utterance_id != utterance_id_) { |
149 // This utterance must have been interrupted or cancelled. | 136 // This utterance must have been interrupted or cancelled. |
150 return; | 137 return; |
151 } | 138 } |
| 139 chromeos::SpeechSynthesizerClient* speech_synthesizer_client = |
| 140 chromeos::DBusThreadManager::Get()->speech_synthesizer_client(); |
| 141 speech_synthesizer_client->IsSpeaking(base::Bind( |
| 142 &ExtensionTtsPlatformImplChromeOs::ContinuePollingIfSpeechIsNotFinished, |
| 143 weak_ptr_factory_.GetWeakPtr(), utterance_id)); |
| 144 } |
152 | 145 |
153 chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); | 146 void ExtensionTtsPlatformImplChromeOs::ContinuePollingIfSpeechIsNotFinished( |
154 ExtensionTtsController* controller = ExtensionTtsController::GetInstance(); | 147 int utterance_id, bool is_speaking) { |
155 | 148 if (utterance_id != utterance_id_) { |
156 if (!cros_library->EnsureLoaded()) { | 149 // This utterance must have been interrupted or cancelled. |
157 controller->OnTtsEvent( | |
158 utterance_id_, TTS_EVENT_ERROR, 0, kCrosLibraryNotLoadedError); | |
159 return; | 150 return; |
160 } | 151 } |
161 | 152 if (!is_speaking) { |
162 if (!cros_library->GetSpeechSynthesisLibrary()->IsSpeaking()) { | 153 ExtensionTtsController* controller = ExtensionTtsController::GetInstance(); |
163 controller->OnTtsEvent( | 154 controller->OnTtsEvent( |
164 utterance_id_, TTS_EVENT_END, utterance_length_, std::string()); | 155 utterance_id_, TTS_EVENT_END, utterance_length_, std::string()); |
165 return; | 156 return; |
166 } | 157 } |
167 | 158 // Continue polling. |
168 MessageLoop::current()->PostDelayedTask( | 159 MessageLoop::current()->PostDelayedTask( |
169 FROM_HERE, base::Bind( | 160 FROM_HERE, base::Bind( |
170 &ExtensionTtsPlatformImplChromeOs::PollUntilSpeechFinishes, | 161 &ExtensionTtsPlatformImplChromeOs::PollUntilSpeechFinishes, |
171 ptr_factory_.GetWeakPtr(), | 162 weak_ptr_factory_.GetWeakPtr(), |
172 utterance_id), | 163 utterance_id), |
173 kSpeechCheckDelayIntervalMs); | 164 kSpeechCheckDelayIntervalMs); |
174 } | 165 } |
175 | 166 |
176 void ExtensionTtsPlatformImplChromeOs::AppendSpeakOption( | 167 void ExtensionTtsPlatformImplChromeOs::AppendSpeakOption( |
177 std::string key, | 168 std::string key, |
178 std::string value, | 169 std::string value, |
179 std::string* options) { | 170 std::string* options) { |
180 *options += | 171 *options += |
181 key + | 172 key + |
182 chromeos::SpeechSynthesisLibrary::kSpeechPropertyEquals + | 173 chromeos::SpeechSynthesizerClient::kSpeechPropertyEquals + |
183 value + | 174 value + |
184 chromeos::SpeechSynthesisLibrary::kSpeechPropertyDelimiter; | 175 chromeos::SpeechSynthesizerClient::kSpeechPropertyDelimiter; |
185 } | 176 } |
186 | 177 |
187 // static | 178 // static |
188 ExtensionTtsPlatformImplChromeOs* | 179 ExtensionTtsPlatformImplChromeOs* |
189 ExtensionTtsPlatformImplChromeOs::GetInstance() { | 180 ExtensionTtsPlatformImplChromeOs::GetInstance() { |
190 return Singleton<ExtensionTtsPlatformImplChromeOs>::get(); | 181 return Singleton<ExtensionTtsPlatformImplChromeOs>::get(); |
191 } | 182 } |
OLD | NEW |