 Chromium Code Reviews
 Chromium Code Reviews Issue 10938009:
  Views fuzzing for Aura and Windows  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@master
    
  
    Issue 10938009:
  Views fuzzing for Aura and Windows  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "ui/views/view.h" | 5 #include "ui/views/view.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 | 8 | 
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" | 
| 10 #include "base/logging.h" | 10 #include "base/logging.h" | 
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "ui/gfx/canvas.h" | 21 #include "ui/gfx/canvas.h" | 
| 22 #include "ui/gfx/interpolated_transform.h" | 22 #include "ui/gfx/interpolated_transform.h" | 
| 23 #include "ui/gfx/path.h" | 23 #include "ui/gfx/path.h" | 
| 24 #include "ui/gfx/point3.h" | 24 #include "ui/gfx/point3.h" | 
| 25 #include "ui/gfx/skia_util.h" | 25 #include "ui/gfx/skia_util.h" | 
| 26 #include "ui/gfx/transform.h" | 26 #include "ui/gfx/transform.h" | 
| 27 #include "ui/views/background.h" | 27 #include "ui/views/background.h" | 
| 28 #include "ui/views/context_menu_controller.h" | 28 #include "ui/views/context_menu_controller.h" | 
| 29 #include "ui/views/drag_controller.h" | 29 #include "ui/views/drag_controller.h" | 
| 30 #include "ui/views/layout/layout_manager.h" | 30 #include "ui/views/layout/layout_manager.h" | 
| 31 #include "ui/views/view_constants.h" | |
| 31 #include "ui/views/views_delegate.h" | 32 #include "ui/views/views_delegate.h" | 
| 32 #include "ui/views/widget/native_widget_private.h" | 33 #include "ui/views/widget/native_widget_private.h" | 
| 33 #include "ui/views/widget/root_view.h" | 34 #include "ui/views/widget/root_view.h" | 
| 34 #include "ui/views/widget/tooltip_manager.h" | 35 #include "ui/views/widget/tooltip_manager.h" | 
| 35 #include "ui/views/widget/widget.h" | 36 #include "ui/views/widget/widget.h" | 
| 36 | 37 | 
| 37 #if defined(OS_WIN) | 38 #if defined(OS_WIN) | 
| 38 #include "base/win/scoped_gdi_object.h" | 39 #include "base/win/scoped_gdi_object.h" | 
| 39 #include "ui/views/accessibility/native_view_accessibility_win.h" | 40 #include "ui/views/accessibility/native_view_accessibility_win.h" | 
| 40 #endif | 41 #endif | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 }; | 75 }; | 
| 75 | 76 | 
| 76 // Returns the top view in |view|'s hierarchy. | 77 // Returns the top view in |view|'s hierarchy. | 
| 77 const views::View* GetHierarchyRoot(const views::View* view) { | 78 const views::View* GetHierarchyRoot(const views::View* view) { | 
| 78 const views::View* root = view; | 79 const views::View* root = view; | 
| 79 while (root && root->parent()) | 80 while (root && root->parent()) | 
| 80 root = root->parent(); | 81 root = root->parent(); | 
| 81 return root; | 82 return root; | 
| 82 } | 83 } | 
| 83 | 84 | 
| 85 // Returns a ratio of the area of intersection compared to the smaller of | |
| 86 // the two rectangles. | |
| 87 double OverlapProportion(const gfx::Rect& rect_one, | |
| 88 const gfx::Rect& rect_two) { | |
| 89 gfx::Rect intersection = rect_one.Intersect(rect_two); | |
| 90 double rect_one_area = rect_one.size().GetArea();; | |
| 91 double rect_two_area = rect_two.size().GetArea();; | |
| 92 double intersection_area = intersection.size().GetArea();; | |
| 93 if ((rect_one_area <= 0) || (rect_two_area <= 0)) | |
| 94 return 0.0; | |
| 95 if (rect_one_area > rect_two_area) | |
| 96 return intersection_area / rect_two_area; | |
| 97 else | |
| 98 return intersection_area / rect_one_area; | |
| 99 } | |
| 100 | |
| 101 // The positive distance from |pos| to the nearest endpoint of the interval | |
| 102 // [start, end] is returned if |pos| lies within the interval, otherwise | |
| 103 // 0 is returned. | |
| 104 int DistanceToInterval(int pos, int start, int end) { | |
| 105 if (pos < start) | |
| 106 return start - pos; | |
| 107 if (pos > end) | |
| 108 return pos - end; | |
| 109 return 0; | |
| 110 } | |
| 111 | |
| 112 // Returns the square of the distance from |point| to the center line of | |
| 113 // |target_rect|. The center line of a rectangle is obtained by repeatedly | |
| 114 // stripping away 1px borders around the rectangle until a line remains. | |
| 115 int DistanceSquaredFromCenterLineToPoint(const gfx::Point& point, | |
| 116 const gfx::Rect& target_rect) { | |
| 117 gfx::Point center_point = target_rect.CenterPoint(); | |
| 118 int dx = center_point.x() - point.x(); | |
| 119 int dy = center_point.y() - point.y(); | |
| 120 | |
| 121 if (target_rect.width() > target_rect.height()) { | |
| 122 dx = DistanceToInterval(point.x(), | |
| 123 target_rect.x() + (target_rect.height() / 2), | |
| 124 target_rect.right() - (target_rect.height() / 2)); | |
| 125 } else { | |
| 126 dy = DistanceToInterval(point.y(), | |
| 127 target_rect.y() + (target_rect.width() / 2), | |
| 128 target_rect.bottom() - (target_rect.width() / 2)); | |
| 129 } | |
| 130 return (dx * dx) + (dy * dy); | |
| 131 } | |
| 132 | |
| 84 } // namespace | 133 } // namespace | 
| 85 | 134 | 
| 86 namespace views { | 135 namespace views { | 
| 87 | 136 | 
| 88 // static | 137 // static | 
| 89 ViewsDelegate* ViewsDelegate::views_delegate = NULL; | 138 ViewsDelegate* ViewsDelegate::views_delegate = NULL; | 
| 90 | 139 | 
| 91 // static | 140 // static | 
| 92 const char View::kViewClassName[] = "views/View"; | 141 const char View::kViewClassName[] = "views/View"; | 
| 93 | 142 | 
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 target->ConvertPointFromAncestor(root, point); | 669 target->ConvertPointFromAncestor(root, point); | 
| 621 | 670 | 
| 622 // API defines NULL |source| as returning the point in screen coordinates. | 671 // API defines NULL |source| as returning the point in screen coordinates. | 
| 623 if (!source) { | 672 if (!source) { | 
| 624 *point = point->Subtract( | 673 *point = point->Subtract( | 
| 625 root->GetWidget()->GetClientAreaBoundsInScreen().origin()); | 674 root->GetWidget()->GetClientAreaBoundsInScreen().origin()); | 
| 626 } | 675 } | 
| 627 } | 676 } | 
| 628 | 677 | 
| 629 // static | 678 // static | 
| 679 void View::ConvertRectToTarget(const View* source, | |
| 680 const View* target, | |
| 681 gfx::Rect* rect) { | |
| 682 gfx::Point rect_location(rect->x(), rect->y()); | |
| 683 View::ConvertPointToTarget(source, target, &rect_location); | |
| 684 rect->set_origin(rect_location); | |
| 
sadrul
2012/09/18 17:29:22
Just converting the origin isn't sufficient. You w
 | |
| 685 } | |
| 686 | |
| 687 // static | |
| 630 void View::ConvertPointToWidget(const View* src, gfx::Point* p) { | 688 void View::ConvertPointToWidget(const View* src, gfx::Point* p) { | 
| 631 DCHECK(src); | 689 DCHECK(src); | 
| 632 DCHECK(p); | 690 DCHECK(p); | 
| 633 | 691 | 
| 634 src->ConvertPointForAncestor(NULL, p); | 692 src->ConvertPointForAncestor(NULL, p); | 
| 635 } | 693 } | 
| 636 | 694 | 
| 637 // static | 695 // static | 
| 638 void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) { | 696 void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) { | 
| 639 DCHECK(dest); | 697 DCHECK(dest); | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 742 } | 800 } | 
| 743 | 801 | 
| 744 // static | 802 // static | 
| 745 bool View::get_use_acceleration_when_possible() { | 803 bool View::get_use_acceleration_when_possible() { | 
| 746 return use_acceleration_when_possible; | 804 return use_acceleration_when_possible; | 
| 747 } | 805 } | 
| 748 | 806 | 
| 749 // Input ----------------------------------------------------------------------- | 807 // Input ----------------------------------------------------------------------- | 
| 750 | 808 | 
| 751 View* View::GetEventHandlerForPoint(const gfx::Point& point) { | 809 View* View::GetEventHandlerForPoint(const gfx::Point& point) { | 
| 752 // Walk the child Views recursively looking for the View that most | 810 return GetEventHandler(gfx::Rect(point, gfx::Size(1, 1)), MOUSE); | 
| 753 // tightly encloses the specified point. | 811 } | 
| 812 | |
| 813 View* View::GetEventHandlerForRect(const gfx::Rect& rect) { | |
| 
sadrul
2012/09/18 17:29:22
Without changes in RootView, it is difficult to un
 | |
| 814 // TODO: Consider expanding small (single point) rectangles. | |
| 
tdanderson
2012/09/18 19:19:02
What do you mean by "expanding" small rectangles?
 | |
| 815 return GetEventHandler(rect, TOUCH); | |
| 816 } | |
| 817 | |
| 818 View* View::GetEventHandler(const gfx::Rect& rect, EventType type) { | |
| 
sky
2012/09/18 19:51:41
ordering doesn't match header.
 | |
| 819 View* closest_view = NULL; | |
| 
tdanderson
2012/09/18 19:19:02
I think calling this |closest_view| in your curren
 | |
| 820 View* closest_untouched_view = NULL; | |
| 821 double max_proportion = 0; | |
| 822 int closest_distance = INT_MAX; | |
| 754 for (int i = child_count() - 1; i >= 0; --i) { | 823 for (int i = child_count() - 1; i >= 0; --i) { | 
| 755 View* child = child_at(i); | 824 View* child = child_at(i); | 
| 756 if (!child->visible()) | 825 if (!child->visible()) | 
| 757 continue; | 826 continue; | 
| 758 | 827 | 
| 759 gfx::Point point_in_child_coords(point); | 828 gfx::Rect child_rect(child->bounds()); | 
| 760 ConvertPointToTarget(this, child, &point_in_child_coords); | 829 | 
| 761 if (child->HitTestPoint(point_in_child_coords)) | 830 if (!child_rect.Intersects(rect)) | 
| 762 return child->GetEventHandlerForPoint(point_in_child_coords); | 831 continue; | 
| 
sadrul
2012/09/18 17:29:22
It is important to continue to use the hit-testing
 | |
| 832 | |
| 833 gfx::Rect rect_in_child_coords(rect); | |
| 834 View::ConvertRectToTarget(this, child, &rect_in_child_coords); | |
| 835 View* cur_view = child->GetEventHandler(rect_in_child_coords, type); | |
| 836 if (!cur_view) | |
| 837 continue; | |
| 838 | |
| 839 if (type == MOUSE) | |
| 840 return cur_view; | |
| 841 | |
| 842 gfx::Point touch_center(rect.CenterPoint()); | |
| 843 gfx::Rect cur_rect(cur_view->GetLocalBounds()); | |
| 844 View::ConvertRectToTarget(cur_view, this, &cur_rect); | |
| 845 int distance = DistanceSquaredFromCenterLineToPoint(touch_center, | |
| 846 cur_rect); | |
| 847 double proportion = OverlapProportion(cur_rect, rect); | |
| 848 if (proportion == 0) { | |
| 849 if (distance < closest_distance) { | |
| 850 closest_untouched_view = cur_view; | |
| 851 closest_distance = distance; | |
| 852 } | |
| 853 } else if (!closest_view || proportion > max_proportion) { | |
| 
tdanderson
2012/09/18 19:19:02
I am worried about the case where there are >=2 vi
 | |
| 854 closest_view = cur_view; | |
| 855 max_proportion = proportion; | |
| 856 } | |
| 763 } | 857 } | 
| 764 return this; | 858 | 
| 859 if (closest_view) | |
| 860 return closest_view; | |
| 861 | |
| 862 gfx::Rect view_rect(GetLocalBounds()); | |
| 863 double proportion = OverlapProportion(view_rect, rect); | |
| 864 if (proportion > max_proportion) | |
| 865 return this; | |
| 866 if (closest_untouched_view) | |
| 
tdanderson
2012/09/18 19:19:02
It seems this is only reached if a touch region do
 | |
| 867 return closest_untouched_view; | |
| 868 return type == MOUSE ? this : NULL; | |
| 765 } | 869 } | 
| 766 | 870 | 
| 767 gfx::NativeCursor View::GetCursor(const ui::MouseEvent& event) { | 871 gfx::NativeCursor View::GetCursor(const ui::MouseEvent& event) { | 
| 768 #if defined(OS_WIN) && !defined(USE_AURA) | 872 #if defined(OS_WIN) && !defined(USE_AURA) | 
| 769 static HCURSOR arrow = LoadCursor(NULL, IDC_ARROW); | 873 static HCURSOR arrow = LoadCursor(NULL, IDC_ARROW); | 
| 770 return arrow; | 874 return arrow; | 
| 771 #else | 875 #else | 
| 772 return gfx::kNullCursor; | 876 return gfx::kNullCursor; | 
| 773 #endif | 877 #endif | 
| 774 } | 878 } | 
| (...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2113 gfx::Point widget_location(event.location()); | 2217 gfx::Point widget_location(event.location()); | 
| 2114 ConvertPointToWidget(this, &widget_location); | 2218 ConvertPointToWidget(this, &widget_location); | 
| 2115 GetWidget()->RunShellDrag(this, data, widget_location, drag_operations); | 2219 GetWidget()->RunShellDrag(this, data, widget_location, drag_operations); | 
| 2116 return true; | 2220 return true; | 
| 2117 #else | 2221 #else | 
| 2118 return false; | 2222 return false; | 
| 2119 #endif // !defined(OS_MACOSX) | 2223 #endif // !defined(OS_MACOSX) | 
| 2120 } | 2224 } | 
| 2121 | 2225 | 
| 2122 } // namespace views | 2226 } // namespace views | 
| OLD | NEW |