Commit 966607ad authored by tapted's avatar tapted Committed by Commit bot

Fix SpeechUIModel lifetime issue in Chrome's AppListViewDelegate when switching profiles

The AppListView observes the SpeechUIModel directly, so SpeechUIModel
must outlive profile changes within Chrome's AppListViewDelegate.
Profile changes only recreate the app_list::ContentView and subviews,
which updates app_list::AppListModel observers, but not
app_list::SpeechUIModel observers.

This comes up when switching profiles in the desktop app list.

To fix, this change gives SpeechUIModel a default constructor to
simplify setting the initial speech recognition state, which needs the
profile. Then, decouples the lifetime of the SpeechUIModel from the
Profile in Chrome's AppListViewDelegate.

BUG=405827
TBR=jamescook@chromium.org

Review URL: https://codereview.chromium.org/550883002

Cr-Commit-Position: refs/heads/master@{#293878}
parent b7eac8ac
......@@ -197,8 +197,7 @@ class ExampleSearchResult : public app_list::SearchResult {
class ExampleAppListViewDelegate : public app_list::AppListViewDelegate {
public:
ExampleAppListViewDelegate()
: model_(new app_list::AppListModel),
speech_ui_(app_list::SPEECH_RECOGNITION_OFF) {
: model_(new app_list::AppListModel) {
PopulateApps();
DecorateSearchBox(model_->search_box());
}
......
......@@ -28,8 +28,7 @@ namespace athena {
AppListViewDelegate::AppListViewDelegate(AppModelBuilder* model_builder)
: model_(new app_list::AppListModel),
speech_ui_(new app_list::SpeechUIModel(
app_list::SPEECH_RECOGNITION_OFF)) {
speech_ui_(new app_list::SpeechUIModel) {
model_builder->PopulateApps(model_.get());
// TODO(mukai): get the text from the resources.
model_->search_box()->SetHintText(base::ASCIIToUTF16("Search"));
......
......@@ -173,6 +173,13 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile,
}
profile_manager->GetProfileInfoCache().AddObserver(this);
speech_ui_.reset(new app_list::SpeechUIModel);
#if defined(GOOGLE_CHROME_BUILD)
speech_ui_->set_logo(
*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH));
#endif
SetProfile(profile);
}
......@@ -191,7 +198,6 @@ void AppListViewDelegate::SetProfile(Profile* new_profile) {
// Note: |search_controller_| has a reference to |speech_ui_| so must be
// destroyed first.
search_controller_.reset();
speech_ui_.reset();
custom_page_contents_.clear();
app_list::StartPageService* start_page_service =
app_list::StartPageService::Get(profile_);
......@@ -204,8 +210,10 @@ void AppListViewDelegate::SetProfile(Profile* new_profile) {
}
profile_ = new_profile;
if (!profile_)
if (!profile_) {
speech_ui_->SetSpeechRecognitionState(app_list::SPEECH_RECOGNITION_OFF);
return;
}
model_ =
app_list::AppListSyncableServiceFactory::GetForProfile(profile_)->model();
......@@ -228,15 +236,9 @@ void AppListViewDelegate::SetUpSearchUI() {
if (start_page_service)
start_page_service->AddObserver(this);
speech_ui_.reset(new app_list::SpeechUIModel(
start_page_service ? start_page_service->state()
: app_list::SPEECH_RECOGNITION_OFF));
#if defined(GOOGLE_CHROME_BUILD)
speech_ui_->set_logo(
*ui::ResourceBundle::GetSharedInstance().
GetImageSkiaNamed(IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH));
#endif
speech_ui_->SetSpeechRecognitionState(start_page_service
? start_page_service->state()
: app_list::SPEECH_RECOGNITION_OFF);
search_controller_.reset(new app_list::SearchController(profile_,
model_->search_box(),
......
......@@ -15,10 +15,13 @@ const int16 kDefaultSoundLevel = 200;
} // namespace
SpeechUIModel::SpeechUIModel(SpeechRecognitionState initial_state)
: state_(initial_state),
SpeechUIModel::SpeechUIModel()
: is_final_(false),
sound_level_(0),
state_(app_list::SPEECH_RECOGNITION_OFF),
minimum_sound_level_(kDefaultSoundLevel),
maximum_sound_level_(kDefaultSoundLevel) {}
maximum_sound_level_(kDefaultSoundLevel) {
}
SpeechUIModel::~SpeechUIModel() {}
......
......@@ -17,7 +17,8 @@ namespace app_list {
// SpeechUIModel provides the interface to update the UI for speech recognition.
class APP_LIST_EXPORT SpeechUIModel {
public:
explicit SpeechUIModel(SpeechRecognitionState initial_state);
// Construct the model, initially in state SPEECH_RECOGNITION_OFF.
SpeechUIModel();
virtual ~SpeechUIModel();
void SetSpeechResult(const base::string16& result, bool is_final);
......
......@@ -23,8 +23,7 @@ AppListTestViewDelegate::AppListTestViewDelegate()
toggle_speech_recognition_count_(0),
open_search_result_count_(0),
next_profile_app_count_(0),
model_(new AppListTestModel),
speech_ui_(SPEECH_RECOGNITION_OFF) {
model_(new AppListTestModel) {
model_->SetFoldersEnabled(true);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment