Commit 13738515 authored by mgiuca's avatar mgiuca Committed by Commit bot

ash::ShelfView: CHECK against potentially bad static_casts.

There are a number of static downcasts in ShelfView that are *probably*
correct, but there is no clear proof that they are casting to the
correct type. This patch adds explicit CHECKs before every static_cast
to ensure that we are not casting from an incompatible dynamic type.

drag_view_ now has type ShelfButton*, so it is downcast on assignment,
rather than on many of its uses.

BUG=418460

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

Cr-Commit-Position: refs/heads/master@{#297335}
parent 48714b9b
...@@ -204,6 +204,9 @@ ShelfButton::IconView::~IconView() { ...@@ -204,6 +204,9 @@ ShelfButton::IconView::~IconView() {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// ShelfButton // ShelfButton
// static
const char ShelfButton::kViewClassName[] = "ash/ShelfButton";
ShelfButton* ShelfButton::Create(views::ButtonListener* listener, ShelfButton* ShelfButton::Create(views::ButtonListener* listener,
ShelfButtonHost* host, ShelfButtonHost* host,
ShelfLayoutManager* shelf_layout_manager) { ShelfLayoutManager* shelf_layout_manager) {
...@@ -321,6 +324,10 @@ void ShelfButton::ShowContextMenu(const gfx::Point& p, ...@@ -321,6 +324,10 @@ void ShelfButton::ShowContextMenu(const gfx::Point& p,
} }
} }
const char* ShelfButton::GetClassName() const {
return kViewClassName;
}
bool ShelfButton::OnMousePressed(const ui::MouseEvent& event) { bool ShelfButton::OnMousePressed(const ui::MouseEvent& event) {
CustomButton::OnMousePressed(event); CustomButton::OnMousePressed(event);
host_->PointerPressedOnButton(this, ShelfButtonHost::MOUSE, event); host_->PointerPressedOnButton(this, ShelfButtonHost::MOUSE, event);
......
...@@ -17,6 +17,8 @@ class ShelfLayoutManager; ...@@ -17,6 +17,8 @@ class ShelfLayoutManager;
// Button used for items on the launcher, except for the AppList. // Button used for items on the launcher, except for the AppList.
class ASH_EXPORT ShelfButton : public views::CustomButton { class ASH_EXPORT ShelfButton : public views::CustomButton {
public: public:
static const char kViewClassName[];
// Used to indicate the current state of the button. // Used to indicate the current state of the button.
enum State { enum State {
// Nothing special. Usually represents an app shortcut item with no running // Nothing special. Usually represents an app shortcut item with no running
...@@ -91,6 +93,7 @@ class ASH_EXPORT ShelfButton : public views::CustomButton { ...@@ -91,6 +93,7 @@ class ASH_EXPORT ShelfButton : public views::CustomButton {
}; };
// View overrides: // View overrides:
virtual const char* GetClassName() const OVERRIDE;
virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
......
...@@ -462,7 +462,9 @@ gfx::Rect ShelfView::GetIdealBoundsOfItemIcon(ShelfID id) { ...@@ -462,7 +462,9 @@ gfx::Rect ShelfView::GetIdealBoundsOfItemIcon(ShelfID id) {
index = last_visible_index_ + 1; index = last_visible_index_ + 1;
const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index));
DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type);
ShelfButton* button = static_cast<ShelfButton*>(view_model_->view_at(index)); views::View* view = view_model_->view_at(index);
CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName());
ShelfButton* button = static_cast<ShelfButton*>(view);
gfx::Rect icon_bounds = button->GetIconBounds(); gfx::Rect icon_bounds = button->GetIconBounds();
return gfx::Rect(GetMirroredXWithWidthInView( return gfx::Rect(GetMirroredXWithWidthInView(
ideal_bounds.x() + icon_bounds.x(), icon_bounds.width()), ideal_bounds.x() + icon_bounds.x(), icon_bounds.width()),
...@@ -1068,9 +1070,8 @@ bool ShelfView::HandleRipOffDrag(const ui::LocatedEvent& event) { ...@@ -1068,9 +1070,8 @@ bool ShelfView::HandleRipOffDrag(const ui::LocatedEvent& event) {
int delta = CalculateShelfDistance(screen_location); int delta = CalculateShelfDistance(screen_location);
if (delta > kRipOffDistance) { if (delta > kRipOffDistance) {
// Create a proxy view item which can be moved anywhere. // Create a proxy view item which can be moved anywhere.
ShelfButton* button = static_cast<ShelfButton*>(drag_view_);
CreateDragIconProxy(event.root_location(), CreateDragIconProxy(event.root_location(),
button->GetImage(), drag_view_->GetImage(),
drag_view_, drag_view_,
gfx::Vector2d(0, 0), gfx::Vector2d(0, 0),
kDragAndDropProxyScale); kDragAndDropProxyScale);
...@@ -1152,8 +1153,7 @@ void ShelfView::FinalizeRipOffDrag(bool cancel) { ...@@ -1152,8 +1153,7 @@ void ShelfView::FinalizeRipOffDrag(bool cancel) {
// animation end the flag gets cleared if |snap_back_from_rip_off_view_| // animation end the flag gets cleared if |snap_back_from_rip_off_view_|
// is set. // is set.
snap_back_from_rip_off_view_ = drag_view_; snap_back_from_rip_off_view_ = drag_view_;
ShelfButton* button = static_cast<ShelfButton*>(drag_view_); drag_view_->AddState(ShelfButton::STATE_HIDDEN);
button->AddState(ShelfButton::STATE_HIDDEN);
// When a canceling drag model is happening, the view model is diverged // When a canceling drag model is happening, the view model is diverged
// from the menu model and movements / animations should not be done. // from the menu model and movements / animations should not be done.
model_->Move(current_index, start_drag_index_); model_->Move(current_index, start_drag_index_);
...@@ -1528,6 +1528,7 @@ void ShelfView::ShelfItemChanged(int model_index, const ShelfItem& old_item) { ...@@ -1528,6 +1528,7 @@ void ShelfView::ShelfItemChanged(int model_index, const ShelfItem& old_item) {
case TYPE_PLATFORM_APP: case TYPE_PLATFORM_APP:
case TYPE_DIALOG: case TYPE_DIALOG:
case TYPE_APP_PANEL: { case TYPE_APP_PANEL: {
CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName());
ShelfButton* button = static_cast<ShelfButton*>(view); ShelfButton* button = static_cast<ShelfButton*>(view);
ReflectItemStatus(item, button); ReflectItemStatus(item, button);
// The browser shortcut is currently not a "real" item and as such the // The browser shortcut is currently not a "real" item and as such the
...@@ -1572,7 +1573,8 @@ void ShelfView::PointerPressedOnButton(views::View* view, ...@@ -1572,7 +1573,8 @@ void ShelfView::PointerPressedOnButton(views::View* view,
if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable())
return; // View is being deleted or not draggable, ignore request. return; // View is being deleted or not draggable, ignore request.
drag_view_ = view; CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName());
drag_view_ = static_cast<ShelfButton*>(view);
drag_origin_ = gfx::Point(event.x(), event.y()); drag_origin_ = gfx::Point(event.x(), event.y());
UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage",
layout_manager_->SelectValueForShelfAlignment( layout_manager_->SelectValueForShelfAlignment(
...@@ -1866,6 +1868,7 @@ void ShelfView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { ...@@ -1866,6 +1868,7 @@ void ShelfView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) {
for (int index = 0; index < view_model_->view_size(); index++) { for (int index = 0; index < view_model_->view_size(); index++) {
views::View* view = view_model_->view_at(index); views::View* view = view_model_->view_at(index);
if (view == snap_back_from_rip_off_view_) { if (view == snap_back_from_rip_off_view_) {
CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName());
ShelfButton* button = static_cast<ShelfButton*>(view); ShelfButton* button = static_cast<ShelfButton*>(view);
button->ClearState(ShelfButton::STATE_HIDDEN); button->ClearState(ShelfButton::STATE_HIDDEN);
break; break;
......
...@@ -356,7 +356,7 @@ class ASH_EXPORT ShelfView : public views::View, ...@@ -356,7 +356,7 @@ class ASH_EXPORT ShelfView : public views::View,
// The view being dragged. This is set immediately when the mouse is pressed. // The view being dragged. This is set immediately when the mouse is pressed.
// |dragging_| is set only if the mouse is dragged far enough. // |dragging_| is set only if the mouse is dragged far enough.
views::View* drag_view_; ShelfButton* drag_view_;
// Position of the mouse down event in |drag_view_|'s coordinates. // Position of the mouse down event in |drag_view_|'s coordinates.
gfx::Point drag_origin_; gfx::Point drag_origin_;
......
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