Home | History | Annotate | Download | only in prefs
      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 <string>
      6 
      7 #include "base/command_line.h"
      8 #include "base/file_util.h"
      9 #include "base/files/scoped_temp_dir.h"
     10 #include "base/json/json_file_value_serializer.h"
     11 #include "base/path_service.h"
     12 #include "base/test/test_file_util.h"
     13 #include "base/values.h"
     14 #include "build/build_config.h"
     15 #include "chrome/browser/ui/browser.h"
     16 #include "chrome/browser/ui/browser_window.h"
     17 #include "chrome/browser/ui/browser_window_state.h"
     18 #include "chrome/common/chrome_constants.h"
     19 #include "chrome/common/chrome_paths.h"
     20 #include "chrome/common/pref_names.h"
     21 #include "chrome/test/base/in_process_browser_test.h"
     22 #include "chrome/test/base/test_switches.h"
     23 #include "chrome/test/base/testing_profile.h"
     24 #include "chrome/test/base/ui_test_utils.h"
     25 #include "ui/gfx/rect.h"
     26 
     27 // On GTK, resizing happens asynchronously and we currently don't have a way to
     28 // get called back (it's probably possible, but we don't have that code). Since
     29 // the GTK code is going away, not spending more time on this.
     30 #if !defined(TOOLKIT_GTK)
     31 
     32 typedef InProcessBrowserTest PreservedWindowPlacement;
     33 
     34 IN_PROC_BROWSER_TEST_F(PreservedWindowPlacement, PRE_Test) {
     35   browser()->window()->SetBounds(gfx::Rect(20, 30, 400, 500));
     36 }
     37 
     38 // Fails on Chrome OS as the browser thinks it is restarting after a crash, see
     39 // http://crbug.com/168044
     40 #if defined(OS_CHROMEOS)
     41 #define MAYBE_Test DISABLED_Test
     42 #else
     43 #define MAYBE_Test Test
     44 #endif
     45 IN_PROC_BROWSER_TEST_F(PreservedWindowPlacement, MAYBE_Test) {
     46 #if defined(OS_WIN) && defined(USE_ASH)
     47   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
     48   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
     49     return;
     50 #endif
     51 
     52   gfx::Rect bounds = browser()->window()->GetBounds();
     53   gfx::Rect expected_bounds(gfx::Rect(20, 30, 400, 500));
     54   ASSERT_EQ(expected_bounds.ToString(), bounds.ToString());
     55 }
     56 
     57 #endif  // defined(TOOLKIT_GTK)
     58 
     59 class PreferenceServiceTest : public InProcessBrowserTest {
     60  public:
     61   explicit PreferenceServiceTest(bool new_profile) : new_profile_(new_profile) {
     62   }
     63 
     64   virtual bool SetUpUserDataDirectory() OVERRIDE {
     65     base::FilePath user_data_directory;
     66     PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
     67 
     68     base::FilePath reference_pref_file;
     69     if (new_profile_) {
     70       reference_pref_file = ui_test_utils::GetTestFilePath(
     71           base::FilePath().AppendASCII("profiles").
     72                      AppendASCII("window_placement").
     73                      AppendASCII("Default"),
     74           base::FilePath().Append(chrome::kPreferencesFilename));
     75       tmp_pref_file_ =
     76           user_data_directory.AppendASCII(TestingProfile::kTestUserProfileDir);
     77       CHECK(file_util::CreateDirectory(tmp_pref_file_));
     78       tmp_pref_file_ = tmp_pref_file_.Append(chrome::kPreferencesFilename);
     79     } else {
     80       reference_pref_file = ui_test_utils::GetTestFilePath(
     81           base::FilePath().AppendASCII("profiles").
     82                      AppendASCII("window_placement"),
     83           base::FilePath().Append(chrome::kLocalStateFilename));
     84       tmp_pref_file_ = user_data_directory.Append(chrome::kLocalStateFilename);
     85     }
     86 
     87     CHECK(base::PathExists(reference_pref_file));
     88     // Copy only the Preferences file if |new_profile_|, or Local State if not,
     89     // and the rest will be automatically created.
     90     CHECK(base::CopyFile(reference_pref_file, tmp_pref_file_));
     91 
     92 #if defined(OS_WIN)
     93     // Make the copy writable.  On POSIX we assume the umask allows files
     94     // we create to be writable.
     95     CHECK(::SetFileAttributesW(tmp_pref_file_.value().c_str(),
     96         FILE_ATTRIBUTE_NORMAL));
     97 #endif
     98     return true;
     99   }
    100 
    101  protected:
    102   base::FilePath tmp_pref_file_;
    103 
    104  private:
    105   bool new_profile_;
    106 };
    107 
    108 #if defined(OS_WIN) || defined(OS_MACOSX)
    109 // This test verifies that the window position from the prefs file is restored
    110 // when the app restores.  This doesn't really make sense on Linux, where
    111 // the window manager might fight with you over positioning.  However, we
    112 // might be able to make this work on buildbots.
    113 // TODO(port): revisit this.
    114 
    115 class PreservedWindowPlacementIsLoaded : public PreferenceServiceTest {
    116  public:
    117   PreservedWindowPlacementIsLoaded() : PreferenceServiceTest(true) {
    118   }
    119 };
    120 
    121 IN_PROC_BROWSER_TEST_F(PreservedWindowPlacementIsLoaded, Test) {
    122 #if defined(OS_WIN) && defined(USE_ASH)
    123   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    124   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    125     return;
    126 #endif
    127 
    128   // The window should open with the new reference profile, with window
    129   // placement values stored in the user data directory.
    130   JSONFileValueSerializer deserializer(tmp_pref_file_);
    131   scoped_ptr<Value> root(deserializer.Deserialize(NULL, NULL));
    132 
    133   ASSERT_TRUE(root.get());
    134   ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
    135 
    136   DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get());
    137 
    138   // Retrieve the screen rect for the launched window
    139   gfx::Rect bounds = browser()->window()->GetRestoredBounds();
    140 
    141   // Retrieve the expected rect values from "Preferences"
    142   int bottom = 0;
    143   std::string kBrowserWindowPlacement(prefs::kBrowserWindowPlacement);
    144   EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".bottom",
    145       &bottom));
    146   EXPECT_EQ(bottom, bounds.y() + bounds.height());
    147 
    148   int top = 0;
    149   EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".top",
    150       &top));
    151   EXPECT_EQ(top, bounds.y());
    152 
    153   int left = 0;
    154   EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".left",
    155       &left));
    156   EXPECT_EQ(left, bounds.x());
    157 
    158   int right = 0;
    159   EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".right",
    160       &right));
    161   EXPECT_EQ(right, bounds.x() + bounds.width());
    162 
    163   // Find if launched window is maximized.
    164   bool is_window_maximized = browser()->window()->IsMaximized();
    165   bool is_maximized = false;
    166   EXPECT_TRUE(root_dict->GetBoolean(kBrowserWindowPlacement + ".maximized",
    167       &is_maximized));
    168   EXPECT_EQ(is_maximized, is_window_maximized);
    169 }
    170 #endif
    171 
    172 #if defined(OS_WIN) || defined(OS_MACOSX)
    173 
    174 class PreservedWindowPlacementIsMigrated : public PreferenceServiceTest {
    175  public:
    176   PreservedWindowPlacementIsMigrated() : PreferenceServiceTest(false) {
    177   }
    178 };
    179 
    180 IN_PROC_BROWSER_TEST_F(PreservedWindowPlacementIsMigrated, Test) {
    181 #if defined(OS_WIN) && defined(USE_ASH)
    182   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    183   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    184     return;
    185 #endif
    186 
    187   // The window should open with the old reference profile, with window
    188   // placement values stored in Local State.
    189 
    190   JSONFileValueSerializer deserializer(tmp_pref_file_);
    191   scoped_ptr<Value> root(deserializer.Deserialize(NULL, NULL));
    192 
    193   ASSERT_TRUE(root.get());
    194   ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
    195 
    196   // Retrieve the screen rect for the launched window
    197   gfx::Rect bounds = browser()->window()->GetRestoredBounds();
    198 
    199   // Values from old reference profile in Local State should have been
    200   // correctly migrated to the user's Preferences -- if so, the window
    201   // should be set to values taken from the user's Local State.
    202   DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get());
    203 
    204   // Retrieve the expected rect values from User Preferences, where they
    205   // should have been migrated from Local State.
    206   int bottom = 0;
    207   std::string kBrowserWindowPlacement(prefs::kBrowserWindowPlacement);
    208   EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".bottom",
    209       &bottom));
    210   EXPECT_EQ(bottom, bounds.y() + bounds.height());
    211 
    212   int top = 0;
    213   EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".top",
    214       &top));
    215   EXPECT_EQ(top, bounds.y());
    216 
    217   int left = 0;
    218   EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".left",
    219       &left));
    220   EXPECT_EQ(left, bounds.x());
    221 
    222   int right = 0;
    223   EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".right",
    224       &right));
    225   EXPECT_EQ(right, bounds.x() + bounds.width());
    226 
    227   // Find if launched window is maximized.
    228   bool is_window_maximized = browser()->window()->IsMaximized();
    229   bool is_maximized = false;
    230   EXPECT_TRUE(root_dict->GetBoolean(kBrowserWindowPlacement + ".maximized",
    231       &is_maximized));
    232   EXPECT_EQ(is_maximized, is_window_maximized);
    233 }
    234 #endif
    235