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 <list>
6#include <vector>
7
8#include "base/prefs/pref_service.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/chrome_notification_types.h"
11#include "chrome/browser/defaults.h"
12#include "chrome/browser/ui/browser.h"
13#include "chrome/browser/ui/browser_iterator.h"
14#include "chrome/browser/ui/browser_window.h"
15#include "chrome/browser/ui/host_desktop.h"
16#include "chrome/common/chrome_paths.h"
17#include "chrome/common/pref_names.h"
18#include "chrome/test/base/in_process_browser_test.h"
19#include "components/sessions/serialized_navigation_entry_test_helper.h"
20#include "content/public/browser/notification_service.h"
21#include "content/public/test/test_utils.h"
22
23namespace {
24const char* test_app_popup_name1 = "TestApp1";
25const char* test_app_popup_name2 = "TestApp2";
26}
27
28class SessionRestoreTestChromeOS : public InProcessBrowserTest {
29 public:
30  virtual ~SessionRestoreTestChromeOS() {}
31
32 protected:
33  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
34    InProcessBrowserTest::SetUpCommandLine(command_line);
35  }
36
37  Browser* CreateBrowserWithParams(Browser::CreateParams params) {
38    Browser* browser = new Browser(params);
39    AddBlankTabAndShow(browser);
40    browser_list_.push_back(browser);
41    return browser;
42  }
43
44  bool CloseBrowser(Browser* browser) {
45    for (std::list<Browser*>::iterator iter = browser_list_.begin();
46         iter != browser_list_.end(); ++iter) {
47      if (*iter == browser) {
48        CloseBrowserSynchronously(*iter);
49        browser_list_.erase(iter);
50        return true;
51      }
52    }
53    return false;
54  }
55
56  void CloseBrowserSynchronously(Browser* browser) {
57    content::WindowedNotificationObserver observer(
58        chrome::NOTIFICATION_BROWSER_CLOSED,
59        content::NotificationService::AllSources());
60    browser->window()->Close();
61    observer.Wait();
62  }
63
64  Browser::CreateParams CreateParamsForApp(const std::string name,
65                                           bool trusted) {
66    return Browser::CreateParams::CreateForApp(
67        name, trusted, gfx::Rect(), profile(), chrome::GetActiveDesktop());
68  }
69
70  // Simluate restarting the browser
71  void SetRestart() {
72    PrefService* pref_service = g_browser_process->local_state();
73    pref_service->SetBoolean(prefs::kWasRestarted, true);
74  }
75
76  Profile* profile() { return browser()->profile(); }
77
78  std::list<Browser*> browser_list_;
79};
80
81// Thse tests are in pairs. The PRE_ test creates some browser windows and
82// the following test confirms that the correct windows are restored after a
83// restart.
84
85IN_PROC_BROWSER_TEST_F(SessionRestoreTestChromeOS, PRE_RestoreBrowserWindows) {
86  // One browser window is always created by default.
87  EXPECT_TRUE(browser());
88  // Create a second normal browser window.
89  CreateBrowserWithParams(
90      Browser::CreateParams(profile(), chrome::GetActiveDesktop()));
91  // Create a third incognito browser window which should not get restored.
92  CreateBrowserWithParams(Browser::CreateParams(
93      profile()->GetOffTheRecordProfile(), chrome::GetActiveDesktop()));
94  SetRestart();
95}
96
97IN_PROC_BROWSER_TEST_F(SessionRestoreTestChromeOS, RestoreBrowserWindows) {
98  size_t total_count = 0;
99  size_t incognito_count = 0;
100  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
101    ++total_count;
102    if (it->profile()->IsOffTheRecord())
103      ++incognito_count;
104  }
105  EXPECT_EQ(2u, total_count);
106  EXPECT_EQ(0u, incognito_count);
107}
108
109IN_PROC_BROWSER_TEST_F(SessionRestoreTestChromeOS, PRE_RestoreAppsV1) {
110  // Create a trusted app popup.
111  CreateBrowserWithParams(CreateParamsForApp(test_app_popup_name1, true));
112  // Create a second trusted app with two popup windows.
113  CreateBrowserWithParams(CreateParamsForApp(test_app_popup_name2, true));
114  CreateBrowserWithParams(CreateParamsForApp(test_app_popup_name2, true));
115  // Create a third untrusted (child) app3 popup. This should not get restored.
116  CreateBrowserWithParams(CreateParamsForApp(test_app_popup_name2, false));
117
118  SetRestart();
119}
120
121IN_PROC_BROWSER_TEST_F(SessionRestoreTestChromeOS, RestoreAppsV1) {
122  size_t total_count = 0;
123  size_t app1_count = 0;
124  size_t app2_count = 0;
125  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
126    ++total_count;
127    if (it->app_name() == test_app_popup_name1)
128      ++app1_count;
129    if (it->app_name() == test_app_popup_name2)
130      ++app2_count;
131  }
132  EXPECT_EQ(1u, app1_count);
133  EXPECT_EQ(2u, app2_count);  // Only the trusted app windows are restored.
134  EXPECT_EQ(4u, total_count);  // Default browser() + 3 app windows
135}
136
137IN_PROC_BROWSER_TEST_F(SessionRestoreTestChromeOS, PRE_RestoreMaximized) {
138  // One browser window is always created by default.
139  ASSERT_TRUE(browser());
140  // Create a second browser window and maximize it.
141  Browser* browser2 = CreateBrowserWithParams(
142      Browser::CreateParams(profile(), chrome::GetActiveDesktop()));
143  browser2->window()->Maximize();
144
145  // Create two app popup windows and maximize the second one.
146  Browser* app_browser1 =
147      CreateBrowserWithParams(CreateParamsForApp(test_app_popup_name1, true));
148  Browser* app_browser2 =
149      CreateBrowserWithParams(CreateParamsForApp(test_app_popup_name1, true));
150  app_browser2->window()->Maximize();
151
152  EXPECT_FALSE(browser()->window()->IsMaximized());
153  EXPECT_TRUE(browser2->window()->IsMaximized());
154  EXPECT_FALSE(app_browser1->window()->IsMaximized());
155  EXPECT_TRUE(app_browser2->window()->IsMaximized());
156
157  SetRestart();
158}
159
160IN_PROC_BROWSER_TEST_F(SessionRestoreTestChromeOS, RestoreMaximized) {
161  size_t total_count = 0;
162  size_t maximized_count = 0;
163  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
164    ++total_count;
165    if (it->window()->IsMaximized())
166      ++maximized_count;
167  }
168  EXPECT_EQ(4u, total_count);
169  EXPECT_EQ(2u, maximized_count);
170}
171