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