| // Copyright 2013 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 "ui/app_list/speech_ui_model.h" | 
 |  | 
 | #include <stdint.h> | 
 |  | 
 | #include <algorithm> | 
 | #include <limits> | 
 |  | 
 | namespace app_list { | 
 |  | 
 | namespace { | 
 |  | 
 | // The default sound level, just gotten from the developer device. | 
 | const int16_t kDefaultSoundLevel = 200; | 
 |  | 
 | }  // namespace | 
 |  | 
 | SpeechUIModel::SpeechUIModel() | 
 |     : is_final_(false), | 
 |       sound_level_(0), | 
 |       state_(app_list::SPEECH_RECOGNITION_OFF), | 
 |       minimum_sound_level_(kDefaultSoundLevel), | 
 |       maximum_sound_level_(kDefaultSoundLevel) { | 
 | } | 
 |  | 
 | SpeechUIModel::~SpeechUIModel() {} | 
 |  | 
 | void SpeechUIModel::SetSpeechResult(const base::string16& result, | 
 |                                     bool is_final) { | 
 |   if (result_ == result && is_final_ == is_final) | 
 |     return; | 
 |  | 
 |   result_ = result; | 
 |   is_final_ = is_final; | 
 |   FOR_EACH_OBSERVER(SpeechUIModelObserver, | 
 |                     observers_, | 
 |                     OnSpeechResult(result, is_final)); | 
 | } | 
 |  | 
 | void SpeechUIModel::UpdateSoundLevel(int16_t level) { | 
 |   if (sound_level_ == level) | 
 |     return; | 
 |  | 
 |   sound_level_ = level; | 
 |  | 
 |   // Tweak the sound level limits adaptively. | 
 |   // - min is the minimum value during the speech recognition starts but speech | 
 |   //   itself hasn't started. | 
 |   // - max is the maximum value when the user speaks. | 
 |   if (state_ == SPEECH_RECOGNITION_IN_SPEECH) | 
 |     maximum_sound_level_ = std::max(level, maximum_sound_level_); | 
 |   else | 
 |     minimum_sound_level_ = std::min(level, minimum_sound_level_); | 
 |  | 
 |   if (maximum_sound_level_ < minimum_sound_level_) { | 
 |     maximum_sound_level_ = std::max( | 
 |         static_cast<int16_t>(minimum_sound_level_ + kDefaultSoundLevel), | 
 |         std::numeric_limits<int16_t>::max()); | 
 |   } | 
 |  | 
 |   int16_t range = maximum_sound_level_ - minimum_sound_level_; | 
 |   uint8_t visible_level = 0; | 
 |   if (range > 0) { | 
 |     int16_t visible_level_in_range = std::min( | 
 |         std::max(minimum_sound_level_, sound_level_), maximum_sound_level_); | 
 |     visible_level = (visible_level_in_range - minimum_sound_level_) * | 
 |                     std::numeric_limits<uint8_t>::max() / range; | 
 |   } | 
 |  | 
 |   FOR_EACH_OBSERVER(SpeechUIModelObserver, | 
 |                     observers_, | 
 |                     OnSpeechSoundLevelChanged(visible_level)); | 
 | } | 
 |  | 
 | void SpeechUIModel::SetSpeechRecognitionState(SpeechRecognitionState new_state, | 
 |                                               bool always_show_ui) { | 
 |   // Don't show the speech view on a change to a network error or if the state | 
 |   // has not changed, unless |always_show_ui| is true. | 
 |   if (!always_show_ui && | 
 |       (state_ == new_state || new_state == SPEECH_RECOGNITION_NETWORK_ERROR)) { | 
 |     state_ = new_state; | 
 |     return; | 
 |   } | 
 |  | 
 |   state_ = new_state; | 
 |  | 
 |   // Revert the min/max sound level to the default. | 
 |   if (state_ != SPEECH_RECOGNITION_RECOGNIZING && | 
 |       state_ != SPEECH_RECOGNITION_IN_SPEECH) { | 
 |     minimum_sound_level_ = kDefaultSoundLevel; | 
 |     maximum_sound_level_ = kDefaultSoundLevel; | 
 |   } | 
 |  | 
 |   FOR_EACH_OBSERVER(SpeechUIModelObserver, | 
 |                     observers_, | 
 |                     OnSpeechRecognitionStateChanged(new_state)); | 
 | } | 
 |  | 
 | void SpeechUIModel::AddObserver(SpeechUIModelObserver* observer) { | 
 |   observers_.AddObserver(observer); | 
 | } | 
 |  | 
 | void SpeechUIModel::RemoveObserver(SpeechUIModelObserver* observer) { | 
 |   observers_.RemoveObserver(observer); | 
 | } | 
 |  | 
 | }  // namespace app_list |