Commit 90fa3056 authored by calamity@chromium.org's avatar calamity@chromium.org

Fix use-after-free when switching profiles in the experimental app list.

This CL fixes an issue where the ContentsSwitcherView would dereference a
pointer to a freed ContentsView.

BUG=384957

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278054 0039d316-1c4b-4281-b951-d872f2087c98
parent 19677409
...@@ -39,8 +39,6 @@ const int kInnerPadding = 1; ...@@ -39,8 +39,6 @@ const int kInnerPadding = 1;
// The maximum allowed time to wait for icon loading in milliseconds. // The maximum allowed time to wait for icon loading in milliseconds.
const int kMaxIconLoadingWaitTimeInMs = 50; const int kMaxIconLoadingWaitTimeInMs = 50;
const int kContentsViewIndex = 1;
} // namespace } // namespace
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -90,6 +88,7 @@ AppListMainView::AppListMainView(AppListViewDelegate* delegate, ...@@ -90,6 +88,7 @@ AppListMainView::AppListMainView(AppListViewDelegate* delegate,
model_(delegate->GetModel()), model_(delegate->GetModel()),
search_box_view_(NULL), search_box_view_(NULL),
contents_view_(NULL), contents_view_(NULL),
contents_switcher_view_(NULL),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
kInnerPadding, kInnerPadding,
...@@ -98,9 +97,7 @@ AppListMainView::AppListMainView(AppListViewDelegate* delegate, ...@@ -98,9 +97,7 @@ AppListMainView::AppListMainView(AppListViewDelegate* delegate,
search_box_view_ = new SearchBoxView(this, delegate); search_box_view_ = new SearchBoxView(this, delegate);
AddChildView(search_box_view_); AddChildView(search_box_view_);
AddContentsView(); AddContentsViews();
if (app_list::switches::IsExperimentalAppListEnabled())
AddChildView(new ContentsSwitcherView(contents_view_));
// Switch the apps grid view to the specified page. // Switch the apps grid view to the specified page.
app_list::PaginationModel* pagination_model = GetAppsPaginationModel(); app_list::PaginationModel* pagination_model = GetAppsPaginationModel();
...@@ -111,9 +108,13 @@ AppListMainView::AppListMainView(AppListViewDelegate* delegate, ...@@ -111,9 +108,13 @@ AppListMainView::AppListMainView(AppListViewDelegate* delegate,
PreloadIcons(parent); PreloadIcons(parent);
} }
void AppListMainView::AddContentsView() { void AppListMainView::AddContentsViews() {
contents_view_ = new ContentsView(this, model_, delegate_); contents_view_ = new ContentsView(this, model_, delegate_);
AddChildViewAt(contents_view_, kContentsViewIndex); AddChildView(contents_view_);
if (app_list::switches::IsExperimentalAppListEnabled()) {
contents_switcher_view_ = new ContentsSwitcherView(contents_view_);
AddChildView(contents_switcher_view_);
}
search_box_view_->set_contents_view(contents_view_); search_box_view_->set_contents_view(contents_view_);
...@@ -164,7 +165,11 @@ void AppListMainView::ModelChanged() { ...@@ -164,7 +165,11 @@ void AppListMainView::ModelChanged() {
search_box_view_->ModelChanged(); search_box_view_->ModelChanged();
delete contents_view_; delete contents_view_;
contents_view_ = NULL; contents_view_ = NULL;
AddContentsView(); if (contents_switcher_view_) {
delete contents_switcher_view_;
contents_switcher_view_ = NULL;
}
AddContentsViews();
Layout(); Layout();
} }
......
...@@ -26,6 +26,7 @@ class AppListItem; ...@@ -26,6 +26,7 @@ class AppListItem;
class AppListModel; class AppListModel;
class AppListViewDelegate; class AppListViewDelegate;
class ApplicationDragAndDropHost; class ApplicationDragAndDropHost;
class ContentsSwitcherView;
class ContentsView; class ContentsView;
class PaginationModel; class PaginationModel;
class SearchBoxView; class SearchBoxView;
...@@ -65,6 +66,9 @@ class APP_LIST_EXPORT AppListMainView : public views::View, ...@@ -65,6 +66,9 @@ class APP_LIST_EXPORT AppListMainView : public views::View,
ApplicationDragAndDropHost* drag_and_drop_host); ApplicationDragAndDropHost* drag_and_drop_host);
ContentsView* contents_view() const { return contents_view_; } ContentsView* contents_view() const { return contents_view_; }
ContentsSwitcherView* contents_switcher_view() const {
return contents_switcher_view_;
}
AppListModel* model() { return model_; } AppListModel* model() { return model_; }
// Returns true if the app list should be centered and in landscape mode. // Returns true if the app list should be centered and in landscape mode.
...@@ -73,7 +77,8 @@ class APP_LIST_EXPORT AppListMainView : public views::View, ...@@ -73,7 +77,8 @@ class APP_LIST_EXPORT AppListMainView : public views::View,
private: private:
class IconLoader; class IconLoader;
void AddContentsView(); // Adds the ContentsView and the ContentsSwitcherView.
void AddContentsViews();
// Gets the PaginationModel owned by the AppsGridView. // Gets the PaginationModel owned by the AppsGridView.
PaginationModel* GetAppsPaginationModel(); PaginationModel* GetAppsPaginationModel();
...@@ -110,6 +115,9 @@ class APP_LIST_EXPORT AppListMainView : public views::View, ...@@ -110,6 +115,9 @@ class APP_LIST_EXPORT AppListMainView : public views::View,
SearchBoxView* search_box_view_; // Owned by views hierarchy. SearchBoxView* search_box_view_; // Owned by views hierarchy.
ContentsView* contents_view_; // Owned by views hierarchy. ContentsView* contents_view_; // Owned by views hierarchy.
// Owned by views hierarchy. NULL in the non-experimental app list.
ContentsSwitcherView* contents_switcher_view_;
// A timer that fires when maximum allowed time to wait for icon loading has // A timer that fires when maximum allowed time to wait for icon loading has
// passed. // passed.
base::OneShotTimer<AppListMainView> icon_loading_wait_timer_; base::OneShotTimer<AppListMainView> icon_loading_wait_timer_;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/app_list_main_view.h"
#include "ui/app_list/views/apps_container_view.h" #include "ui/app_list/views/apps_container_view.h"
#include "ui/app_list/views/apps_grid_view.h" #include "ui/app_list/views/apps_grid_view.h"
#include "ui/app_list/views/contents_switcher_view.h"
#include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/contents_view.h"
#include "ui/app_list/views/search_box_view.h" #include "ui/app_list/views/search_box_view.h"
#include "ui/app_list/views/search_result_list_view.h" #include "ui/app_list/views/search_result_list_view.h"
...@@ -339,10 +340,16 @@ void AppListViewTestContext::RunProfileChangeTest() { ...@@ -339,10 +340,16 @@ void AppListViewTestContext::RunProfileChangeTest() {
StartPageView* start_page_view = StartPageView* start_page_view =
view_->app_list_main_view()->contents_view()->start_page_view(); view_->app_list_main_view()->contents_view()->start_page_view();
ContentsSwitcherView* contents_switcher_view =
view_->app_list_main_view()->contents_switcher_view();
if (test_type_ == EXPERIMENTAL) { if (test_type_ == EXPERIMENTAL) {
EXPECT_NO_FATAL_FAILURE(CheckView(contents_switcher_view));
EXPECT_EQ(view_->app_list_main_view()->contents_view(),
contents_switcher_view->contents_view());
EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view)); EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view));
EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views())); EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views()));
} else { } else {
EXPECT_EQ(NULL, contents_switcher_view);
EXPECT_EQ(NULL, start_page_view); EXPECT_EQ(NULL, start_page_view);
} }
......
...@@ -20,6 +20,8 @@ class ContentsSwitcherView : public views::View, public views::ButtonListener { ...@@ -20,6 +20,8 @@ class ContentsSwitcherView : public views::View, public views::ButtonListener {
explicit ContentsSwitcherView(ContentsView* contents_view); explicit ContentsSwitcherView(ContentsView* contents_view);
virtual ~ContentsSwitcherView(); virtual ~ContentsSwitcherView();
ContentsView* contents_view() const { return contents_view_; }
private: private:
// Adds a switcher button using |resource_id| as the button's image and |tag| // Adds a switcher button using |resource_id| as the button's image and |tag|
// as the button's id. // as the button's id.
......
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