summaryrefslogtreecommitdiffstats
path: root/ui/app_list
diff options
context:
space:
mode:
authortapted@chromium.org <tapted@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-10 07:32:47 +0000
committertapted@chromium.org <tapted@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-10 07:32:47 +0000
commit1cffa0b72693752efc88d37c2142919703bf5add (patch)
tree77e0463893fb05885149d4e021fb20fb4a33216f /ui/app_list
parenta267ff14ffc271d52522affde71803bd29bca3e3 (diff)
downloadchromium_src-1cffa0b72693752efc88d37c2142919703bf5add.zip
chromium_src-1cffa0b72693752efc88d37c2142919703bf5add.tar.gz
chromium_src-1cffa0b72693752efc88d37c2142919703bf5add.tar.bz2
(re)Implement Profile Switching on the Windows App Launcher
Since app list models are now owned by a syncable service, relying on that model emptying out and re-filling to switch profiles on Windows no longer works. This re-implements profile switching for the Windows App Launcher by re-creating its AppListMainView, and all the children, whenever the profile changes in the AppListViewDelegate. BUG=322384 TEST=Switching profiles with the Windows App Launcher should work again. Review URL: https://codereview.chromium.org/106163011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239699 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/app_list')
-rw-r--r--ui/app_list/app_list.gyp1
-rw-r--r--ui/app_list/test/app_list_test_view_delegate.h3
-rw-r--r--ui/app_list/views/app_list_main_view.cc28
-rw-r--r--ui/app_list/views/app_list_main_view.h21
-rw-r--r--ui/app_list/views/app_list_main_view_unittest.cc90
-rw-r--r--ui/app_list/views/app_list_view.cc1
-rw-r--r--ui/app_list/views/page_switcher.h2
-rw-r--r--ui/app_list/views/search_box_view.cc23
-rw-r--r--ui/app_list/views/search_box_view.h6
9 files changed, 148 insertions, 27 deletions
diff --git a/ui/app_list/app_list.gyp b/ui/app_list/app_list.gyp
index 15f01f2..e766c21 100644
--- a/ui/app_list/app_list.gyp
+++ b/ui/app_list/app_list.gyp
@@ -215,6 +215,7 @@
'cocoa/signin_view_controller_unittest.mm',
'cocoa/test/apps_grid_controller_test_helper.h',
'cocoa/test/apps_grid_controller_test_helper.mm',
+ 'views/app_list_main_view_unittest.cc',
'views/apps_grid_view_unittest.cc',
'views/test/apps_grid_view_test_api.cc',
'views/test/apps_grid_view_test_api.h',
diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h
index 16455c9..0142398 100644
--- a/ui/app_list/test/app_list_test_view_delegate.h
+++ b/ui/app_list/test/app_list_test_view_delegate.h
@@ -69,6 +69,7 @@ class AppListTestViewDelegate : public AppListViewDelegate {
// Do a bulk replacement of the items in the model.
void ReplaceTestModel(int item_count);
+ AppListTestModel* ReleaseTestModel() { return model_.release(); }
AppListTestModel* GetTestModel() { return model_.get(); }
private:
@@ -79,6 +80,8 @@ class AppListTestViewDelegate : public AppListViewDelegate {
scoped_ptr<AppListTestModel> model_;
ObserverList<AppListViewDelegateObserver> observers_;
SpeechUIModel speech_ui_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppListTestViewDelegate);
};
} // namespace test
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index a4cd7a9..e6f7a7c 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -81,26 +81,30 @@ AppListMainView::AppListMainView(AppListViewDelegate* delegate,
PaginationModel* pagination_model,
gfx::NativeView parent)
: delegate_(delegate),
+ pagination_model_(pagination_model),
model_(delegate->GetModel()),
search_box_view_(NULL),
contents_view_(NULL),
weak_ptr_factory_(this) {
// Starts icon loading early.
- PreloadIcons(pagination_model, parent);
+ PreloadIcons(parent);
SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
kInnerPadding,
kInnerPadding,
kInnerPadding));
- search_box_view_ = new SearchBoxView(this, delegate, model_);
+ search_box_view_ = new SearchBoxView(this, delegate);
AddChildView(search_box_view_);
+ AddContentsView();
+}
+void AppListMainView::AddContentsView() {
contents_view_ =
new ContentsView(this,
- pagination_model,
+ pagination_model_,
model_,
- delegate ? delegate->GetStartPageContents() : NULL);
+ delegate_ ? delegate_->GetStartPageContents() : NULL);
AddChildView(contents_view_);
search_box_view_->set_contents_view(contents_view_);
@@ -141,13 +145,23 @@ void AppListMainView::Prerender() {
contents_view_->Prerender();
}
+void AppListMainView::ModelChanged() {
+ pending_icon_loaders_.clear();
+ model_ = delegate_->GetModel();
+ search_box_view_->ModelChanged();
+ delete contents_view_;
+ contents_view_ = NULL;
+ pagination_model_->SelectPage(0, false /* animate */);
+ AddContentsView();
+ Layout();
+}
+
void AppListMainView::SetDragAndDropHostOfCurrentAppList(
ApplicationDragAndDropHost* drag_and_drop_host) {
contents_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
}
-void AppListMainView::PreloadIcons(PaginationModel* pagination_model,
- gfx::NativeView parent) {
+void AppListMainView::PreloadIcons(gfx::NativeView parent) {
ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P;
if (parent)
scale_factor = ui::GetScaleFactorForNativeView(parent);
@@ -155,7 +169,7 @@ void AppListMainView::PreloadIcons(PaginationModel* pagination_model,
float scale = ui::GetImageScale(scale_factor);
// |pagination_model| could have -1 as the initial selected page and
// assumes first page (i.e. index 0) will be used in this case.
- const int selected_page = std::max(0, pagination_model->selected_page());
+ const int selected_page = std::max(0, pagination_model_->selected_page());
const int tiles_per_page = kPreferredCols * kPreferredRows;
const int start_model_index = selected_page * tiles_per_page;
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h
index c0de4a0..1e119aa 100644
--- a/ui/app_list/views/app_list_main_view.h
+++ b/ui/app_list/views/app_list_main_view.h
@@ -10,6 +10,7 @@
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
+#include "ui/app_list/app_list_export.h"
#include "ui/app_list/views/apps_grid_view_delegate.h"
#include "ui/app_list/views/search_box_view_delegate.h"
#include "ui/app_list/views/search_result_list_view_delegate.h"
@@ -31,10 +32,10 @@ class SearchBoxView;
// AppListMainView contains the normal view of the app list, which is shown
// when the user is signed in.
-class AppListMainView : public views::View,
- public AppsGridViewDelegate,
- public SearchBoxViewDelegate,
- public SearchResultListViewDelegate {
+class APP_LIST_EXPORT AppListMainView : public views::View,
+ public AppsGridViewDelegate,
+ public SearchBoxViewDelegate,
+ public SearchResultListViewDelegate {
public:
// Takes ownership of |delegate|.
explicit AppListMainView(AppListViewDelegate* delegate,
@@ -48,6 +49,8 @@ class AppListMainView : public views::View,
void Prerender();
+ void ModelChanged();
+
SearchBoxView* search_box_view() const { return search_box_view_; }
// If |drag_and_drop_host| is not NULL it will be called upon drag and drop
@@ -60,10 +63,11 @@ class AppListMainView : public views::View,
private:
class IconLoader;
- // Loads icon image for the apps in the selected page of |pagination_model|.
+ void AddContentsView();
+
+ // Loads icon image for the apps in the selected page of |pagination_model_|.
// |parent| is used to determine the image scale factor to use.
- void PreloadIcons(PaginationModel* pagination_model,
- gfx::NativeView parent);
+ void PreloadIcons(gfx::NativeView parent);
// Invoked when |icon_loading_wait_timer_| fires.
void OnIconLoadingWaitTimer();
@@ -89,7 +93,8 @@ class AppListMainView : public views::View,
virtual void OnResultInstalled(SearchResult* result) OVERRIDE;
virtual void OnResultUninstalled(SearchResult* result) OVERRIDE;
- AppListViewDelegate* delegate_; // Owned by parent (AppListView)
+ AppListViewDelegate* delegate_; // Owned by parent view (AppListView).
+ PaginationModel* pagination_model_; // Owned by AppListController.
AppListModel* model_; // Unowned; ownership is handled by |delegate_|.
SearchBoxView* search_box_view_; // Owned by views hierarchy.
diff --git a/ui/app_list/views/app_list_main_view_unittest.cc b/ui/app_list/views/app_list_main_view_unittest.cc
new file mode 100644
index 0000000..6ca1820
--- /dev/null
+++ b/ui/app_list/views/app_list_main_view_unittest.cc
@@ -0,0 +1,90 @@
+// 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/views/app_list_main_view.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/app_list/pagination_model.h"
+#include "ui/app_list/test/app_list_test_model.h"
+#include "ui/app_list/test/app_list_test_view_delegate.h"
+#include "ui/app_list/views/apps_container_view.h"
+#include "ui/app_list/views/apps_grid_view.h"
+#include "ui/app_list/views/contents_view.h"
+#include "ui/views/test/views_test_base.h"
+#include "ui/views/view_model.h"
+#include "ui/views/widget/widget.h"
+
+namespace app_list {
+namespace test {
+
+namespace {
+
+const int kInitialItems = 2;
+
+class AppListMainViewTest : public views::ViewsTestBase {
+ public:
+ AppListMainViewTest()
+ : widget_(NULL),
+ main_view_(NULL) {}
+
+ virtual ~AppListMainViewTest() {}
+
+ // testing::Test overrides:
+ virtual void SetUp() OVERRIDE {
+ views::ViewsTestBase::SetUp();
+ delegate_.reset(new AppListTestViewDelegate);
+ delegate_->GetTestModel()->PopulateApps(kInitialItems);
+
+ main_view_ =
+ new AppListMainView(delegate_.get(), &pagination_model_, GetContext());
+ main_view_->SetPaintToLayer(true);
+
+ widget_ = new views::Widget;
+ views::Widget::InitParams params =
+ CreateParams(views::Widget::InitParams::TYPE_POPUP);
+ params.bounds.set_size(main_view_->GetPreferredSize());
+ widget_->Init(params);
+
+ widget_->SetContentsView(main_view_);
+ }
+
+ virtual void TearDown() OVERRIDE {
+ widget_->Close();
+ views::ViewsTestBase::TearDown();
+ delegate_.reset();
+ }
+
+ const views::ViewModel* ViewModel() {
+ return main_view_->contents_view()->apps_container_view()->apps_grid_view()
+ ->view_model_for_test();
+ }
+
+ protected:
+ views::Widget* widget_; // Owned by native window.
+ AppListMainView* main_view_; // Owned by |widget_|.
+ PaginationModel pagination_model_;
+ scoped_ptr<AppListTestViewDelegate> delegate_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AppListMainViewTest);
+};
+
+} // namespace
+
+// Tests changing the AppListModel when switching profiles.
+TEST_F(AppListMainViewTest, ModelChanged) {
+ EXPECT_EQ(kInitialItems, ViewModel()->view_size());
+
+ // The model is owned by a profile keyed service, which is never destroyed
+ // until after profile switching.
+ scoped_ptr<AppListModel> old_model(delegate_->ReleaseTestModel());
+
+ const int kReplacementItems = 5;
+ delegate_->ReplaceTestModel(kReplacementItems);
+ main_view_->ModelChanged();
+ EXPECT_EQ(kReplacementItems, ViewModel()->view_size());
+}
+
+} // namespace test
+} // namespace app_list
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index e3d3156..fc15fc5 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -217,6 +217,7 @@ void AppListView::OnProfilesChanged() {
void AppListView::SetProfileByPath(const base::FilePath& profile_path) {
delegate_->SetProfileByPath(profile_path);
+ app_list_main_view_->ModelChanged();
}
void AppListView::AddObserver(AppListViewObserver* observer) {
diff --git a/ui/app_list/views/page_switcher.h b/ui/app_list/views/page_switcher.h
index 7e1ab9d..b05da99 100644
--- a/ui/app_list/views/page_switcher.h
+++ b/ui/app_list/views/page_switcher.h
@@ -50,7 +50,7 @@ class PageSwitcher : public views::View,
virtual void TransitionStarted() OVERRIDE;
virtual void TransitionChanged() OVERRIDE;
- PaginationModel* model_; // Owned by parent AppListView.
+ PaginationModel* model_; // Owned by AppListController.
views::View* buttons_; // Owned by views hierarchy.
DISALLOW_COPY_AND_ASSIGN(PageSwitcher);
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc
index 8344dc2..c975177 100644
--- a/ui/app_list/views/search_box_view.cc
+++ b/ui/app_list/views/search_box_view.cc
@@ -41,16 +41,14 @@ const int kMenuXOffsetFromButton = -7;
} // namespace
SearchBoxView::SearchBoxView(SearchBoxViewDelegate* delegate,
- AppListViewDelegate* view_delegate,
- AppListModel* model)
+ AppListViewDelegate* view_delegate)
: delegate_(delegate),
view_delegate_(view_delegate),
- model_(model),
+ model_(NULL),
icon_view_(new views::ImageView),
speech_button_(NULL),
search_box_(new views::Textfield),
contents_view_(NULL) {
- DCHECK(model_);
AddChildView(icon_view_);
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
@@ -71,16 +69,25 @@ SearchBoxView::SearchBoxView(SearchBoxViewDelegate* delegate,
search_box_->SetController(this);
AddChildView(search_box_);
- model_->search_box()->AddObserver(this);
- IconChanged();
- SpeechRecognitionButtonPropChanged();
- HintTextChanged();
+ ModelChanged();
}
SearchBoxView::~SearchBoxView() {
model_->search_box()->RemoveObserver(this);
}
+void SearchBoxView::ModelChanged() {
+ if (model_)
+ model_->search_box()->RemoveObserver(this);
+
+ model_ = view_delegate_->GetModel();
+ DCHECK(model_);
+ model_->search_box()->AddObserver(this);
+ IconChanged();
+ SpeechRecognitionButtonPropChanged();
+ HintTextChanged();
+}
+
bool SearchBoxView::HasSearch() const {
return !search_box_->text().empty();
}
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h
index 20d15cc..440ffba 100644
--- a/ui/app_list/views/search_box_view.h
+++ b/ui/app_list/views/search_box_view.h
@@ -38,10 +38,10 @@ class SearchBoxView : public views::View,
public SearchBoxModelObserver {
public:
SearchBoxView(SearchBoxViewDelegate* delegate,
- AppListViewDelegate* view_delegate,
- AppListModel* model);
+ AppListViewDelegate* view_delegate);
virtual ~SearchBoxView();
+ void ModelChanged();
bool HasSearch() const;
void ClearSearch();
void InvalidateMenu();
@@ -87,7 +87,7 @@ class SearchBoxView : public views::View,
SearchBoxViewDelegate* delegate_; // Not owned.
AppListViewDelegate* view_delegate_; // Not owned.
- AppListModel* model_; // Owned by AppListView.
+ AppListModel* model_; // Owned by the profile-keyed service.
scoped_ptr<AppListMenuViews> menu_;