Home | History | Annotate | Download | only in views
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/bind.h"
      6 #include "base/bind_helpers.h"
      7 #include "base/files/file_path.h"
      8 #include "base/memory/singleton.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     14 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
     15 #include "chrome/common/url_constants.h"
     16 #include "chrome/test/base/in_process_browser_test.h"
     17 #include "chrome/test/base/ui_test_utils.h"
     18 #include "content/public/browser/browser_context.h"
     19 #include "content/public/browser/render_widget_host_view.h"
     20 #include "content/public/browser/web_contents.h"
     21 #include "testing/gmock/include/gmock/gmock.h"
     22 #include "testing/gtest/include/gtest/gtest.h"
     23 #include "ui/views/controls/webview/web_dialog_view.h"
     24 #include "ui/views/widget/widget.h"
     25 #include "ui/web_dialogs/test/test_web_dialog_delegate.h"
     26 
     27 using content::BrowserContext;
     28 using content::WebContents;
     29 using testing::Eq;
     30 using ui::WebDialogDelegate;
     31 
     32 namespace {
     33 
     34 // Initial size of WebDialog for SizeWindow test case.
     35 const int kInitialWidth = 40;
     36 const int kInitialHeight = 40;
     37 
     38 class TestWebDialogView : public views::WebDialogView {
     39  public:
     40   TestWebDialogView(content::BrowserContext* context,
     41                     WebDialogDelegate* delegate)
     42       : views::WebDialogView(context, delegate, new ChromeWebContentsHandler),
     43         should_quit_on_size_change_(false) {
     44     delegate->GetDialogSize(&last_size_);
     45   }
     46 
     47   void set_should_quit_on_size_change(bool should_quit) {
     48     should_quit_on_size_change_ = should_quit;
     49   }
     50 
     51  private:
     52   // TODO(xiyuan): Update this when WidgetDelegate has bounds change hook.
     53   virtual void SaveWindowPlacement(const gfx::Rect& bounds,
     54                                    ui::WindowShowState show_state) OVERRIDE {
     55     if (should_quit_on_size_change_ && last_size_ != bounds.size()) {
     56       // Schedule message loop quit because we could be called while
     57       // the bounds change call is on the stack and not in the nested message
     58       // loop.
     59       base::MessageLoop::current()->PostTask(
     60           FROM_HERE,
     61           base::Bind(&base::MessageLoop::Quit,
     62                      base::Unretained(base::MessageLoop::current())));
     63     }
     64 
     65     last_size_ = bounds.size();
     66   }
     67 
     68   virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE {
     69     should_quit_on_size_change_ = false;  // No quit when we are closing.
     70     views::WebDialogView::OnDialogClosed(json_retval);
     71   }
     72 
     73   // Whether we should quit message loop when size change is detected.
     74   bool should_quit_on_size_change_;
     75   gfx::Size last_size_;
     76 
     77   DISALLOW_COPY_AND_ASSIGN(TestWebDialogView);
     78 };
     79 
     80 }  // namespace
     81 
     82 class WebDialogBrowserTest : public InProcessBrowserTest {
     83  public:
     84   WebDialogBrowserTest() {}
     85 };
     86 
     87 // http://code.google.com/p/chromium/issues/detail?id=52602
     88 // Windows has some issues resizing windows- an off by one problem,
     89 // and a minimum size that seems too big.  This file isn't included in
     90 // Mac builds yet. On Chrome OS, this test doesn't apply since ChromeOS
     91 // doesn't allow resizing of windows.
     92 IN_PROC_BROWSER_TEST_F(WebDialogBrowserTest, DISABLED_SizeWindow) {
     93   ui::test::TestWebDialogDelegate* delegate =
     94       new ui::test::TestWebDialogDelegate(
     95           GURL(chrome::kChromeUIChromeURLsURL));
     96   delegate->set_size(kInitialWidth, kInitialHeight);
     97 
     98   TestWebDialogView* view =
     99       new TestWebDialogView(browser()->profile(), delegate);
    100   WebContents* web_contents =
    101       browser()->tab_strip_model()->GetActiveWebContents();
    102   ASSERT_TRUE(web_contents != NULL);
    103   views::Widget::CreateWindowWithParent(
    104       view, web_contents->GetTopLevelNativeWindow());
    105   view->GetWidget()->Show();
    106 
    107   // TestWebDialogView should quit current message loop on size change.
    108   view->set_should_quit_on_size_change(true);
    109 
    110   gfx::Rect bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
    111 
    112   gfx::Rect set_bounds = bounds;
    113   gfx::Rect actual_bounds, rwhv_bounds;
    114 
    115   // Bigger than the default in both dimensions.
    116   set_bounds.set_width(400);
    117   set_bounds.set_height(300);
    118 
    119   view->MoveContents(web_contents, set_bounds);
    120   content::RunMessageLoop();  // TestWebDialogView will quit.
    121   actual_bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
    122   EXPECT_EQ(set_bounds, actual_bounds);
    123 
    124   rwhv_bounds =
    125       view->web_contents()->GetRenderWidgetHostView()->GetViewBounds();
    126   EXPECT_LT(0, rwhv_bounds.width());
    127   EXPECT_LT(0, rwhv_bounds.height());
    128   EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
    129   EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
    130 
    131   // Larger in one dimension and smaller in the other.
    132   set_bounds.set_width(550);
    133   set_bounds.set_height(250);
    134 
    135   view->MoveContents(web_contents, set_bounds);
    136   content::RunMessageLoop();  // TestWebDialogView will quit.
    137   actual_bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
    138   EXPECT_EQ(set_bounds, actual_bounds);
    139 
    140   rwhv_bounds =
    141       view->web_contents()->GetRenderWidgetHostView()->GetViewBounds();
    142   EXPECT_LT(0, rwhv_bounds.width());
    143   EXPECT_LT(0, rwhv_bounds.height());
    144   EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
    145   EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
    146 
    147   // Get very small.
    148   gfx::Size min_size = view->GetWidget()->GetMinimumSize();
    149   set_bounds.set_size(min_size);
    150 
    151   view->MoveContents(web_contents, set_bounds);
    152   content::RunMessageLoop();  // TestWebDialogView will quit.
    153   actual_bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
    154   EXPECT_EQ(set_bounds, actual_bounds);
    155 
    156   rwhv_bounds =
    157       view->web_contents()->GetRenderWidgetHostView()->GetViewBounds();
    158   EXPECT_LT(0, rwhv_bounds.width());
    159   EXPECT_LT(0, rwhv_bounds.height());
    160   EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
    161   EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
    162 
    163   // Check to make sure we can't get to 0x0
    164   set_bounds.set_width(0);
    165   set_bounds.set_height(0);
    166 
    167   view->MoveContents(web_contents, set_bounds);
    168   content::RunMessageLoop();  // TestWebDialogView will quit.
    169   actual_bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
    170   EXPECT_LT(0, actual_bounds.width());
    171   EXPECT_LT(0, actual_bounds.height());
    172 }
    173