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 "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
6
7#include "base/prefs/pref_registry_simple.h"
8#include "base/prefs/testing_pref_service.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/browser_shutdown.h"
11#include "chrome/browser/lifetime/application_lifetime.h"
12#include "chrome/browser/profiles/profile_manager.h"
13#include "chrome/browser/ui/browser.h"
14#include "chrome/browser/ui/browser_commands.h"
15#include "chrome/browser/ui/browser_list.h"
16#include "chrome/browser/ui/host_desktop.h"
17#include "chrome/browser/ui/tabs/tab_strip_model.h"
18#include "chrome/common/pref_names.h"
19#include "chrome/test/base/browser_with_test_window_test.h"
20#include "chrome/test/base/test_browser_window.h"
21#include "chrome/test/base/testing_browser_process.h"
22
23typedef BrowserWithTestWindowTest BrowserListTest;
24
25namespace {
26
27// Helper function to iterate and count all the tabs.
28size_t CountAllTabs() {
29  size_t count = 0;
30  for (TabContentsIterator iterator; !iterator.done(); iterator.Next())
31    ++count;
32  return count;
33}
34
35}  // namespace
36
37TEST_F(BrowserListTest, TabContentsIteratorVerifyCount) {
38  // Make sure we have 1 window to start with.
39  EXPECT_EQ(1U,
40            BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->size());
41
42  EXPECT_EQ(0U, CountAllTabs());
43
44  // Create more browsers/windows.
45  Browser::CreateParams native_params(profile(),
46                                      chrome::HOST_DESKTOP_TYPE_NATIVE);
47  scoped_ptr<Browser> browser2(
48      chrome::CreateBrowserWithTestWindowForParams(&native_params));
49  // Create browser 3 and 4 on the Ash desktop (the TabContentsIterator
50  // shouldn't see the difference).
51  Browser::CreateParams ash_params(profile(), chrome::HOST_DESKTOP_TYPE_ASH);
52  scoped_ptr<Browser> browser3(
53      chrome::CreateBrowserWithTestWindowForParams(&ash_params));
54  scoped_ptr<Browser> browser4(
55      chrome::CreateBrowserWithTestWindowForParams(&ash_params));
56
57  // Sanity checks.
58#if defined(OS_CHROMEOS)
59  // The ash desktop is the native desktop on Chrome OS.
60  EXPECT_EQ(4U,
61            BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->size());
62#else
63  EXPECT_EQ(2U,
64            BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->size());
65  EXPECT_EQ(2U,
66            BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH)->size());
67#endif
68  EXPECT_EQ(0, browser()->tab_strip_model()->count());
69  EXPECT_EQ(0, browser2->tab_strip_model()->count());
70  EXPECT_EQ(0, browser3->tab_strip_model()->count());
71  EXPECT_EQ(0, browser4->tab_strip_model()->count());
72
73  EXPECT_EQ(0U, CountAllTabs());
74
75  // Add some tabs.
76  for (size_t i = 0; i < 3; ++i)
77    chrome::NewTab(browser2.get());
78  chrome::NewTab(browser3.get());
79
80  EXPECT_EQ(4U, CountAllTabs());
81
82  // Close some tabs.
83  browser2->tab_strip_model()->CloseAllTabs();
84
85  EXPECT_EQ(1U, CountAllTabs());
86
87  // Add lots of tabs.
88  for (size_t i = 0; i < 41; ++i)
89    chrome::NewTab(browser());
90
91  EXPECT_EQ(42U, CountAllTabs());
92  // Close all remaining tabs to keep all the destructors happy.
93  browser3->tab_strip_model()->CloseAllTabs();
94}
95
96TEST_F(BrowserListTest, TabContentsIteratorVerifyBrowser) {
97  // Make sure we have 1 window to start with.
98  EXPECT_EQ(1U,
99            BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->size());
100
101  // Create more browsers/windows.
102  Browser::CreateParams native_params(profile(),
103                                      chrome::HOST_DESKTOP_TYPE_NATIVE);
104  scoped_ptr<Browser> browser2(
105      chrome::CreateBrowserWithTestWindowForParams(&native_params));
106  // Create browser 3 on the Ash desktop (the TabContentsIterator shouldn't see
107  // the difference).
108  Browser::CreateParams ash_params(profile(), chrome::HOST_DESKTOP_TYPE_ASH);
109  scoped_ptr<Browser> browser3(
110      chrome::CreateBrowserWithTestWindowForParams(&ash_params));
111
112  // Sanity checks.
113#if defined(OS_CHROMEOS)
114  // The ash desktop is the native desktop on Chrome OS.
115  EXPECT_EQ(3U,
116            BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->size());
117#else
118  EXPECT_EQ(2U,
119            BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->size());
120  EXPECT_EQ(1U,
121            BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH)->size());
122#endif
123  EXPECT_EQ(0, browser()->tab_strip_model()->count());
124  EXPECT_EQ(0, browser2->tab_strip_model()->count());
125  EXPECT_EQ(0, browser3->tab_strip_model()->count());
126
127  EXPECT_EQ(0U, CountAllTabs());
128
129  // Add some tabs.
130  for (size_t i = 0; i < 3; ++i)
131    chrome::NewTab(browser2.get());
132  for (size_t i = 0; i < 2; ++i)
133    chrome::NewTab(browser3.get());
134
135  size_t count = 0;
136  for (TabContentsIterator iterator; !iterator.done(); iterator.Next(),
137                                                       ++count) {
138    if (count < 3)
139      EXPECT_EQ(browser2.get(), iterator.browser());
140    else if (count < 5)
141      EXPECT_EQ(browser3.get(), iterator.browser());
142    else
143      ADD_FAILURE();
144  }
145
146  // Close some tabs.
147  browser2->tab_strip_model()->CloseAllTabs();
148  browser3->tab_strip_model()->CloseWebContentsAt(1, TabStripModel::CLOSE_NONE);
149
150  count = 0;
151  for (TabContentsIterator iterator; !iterator.done(); iterator.Next(),
152                                                       ++count) {
153    if (count == 0)
154      EXPECT_EQ(browser3.get(), iterator.browser());
155    else
156      ADD_FAILURE();
157  }
158
159  // Now make it one tab per browser.
160  chrome::NewTab(browser());
161  chrome::NewTab(browser2.get());
162
163  count = 0;
164  for (TabContentsIterator iterator; !iterator.done(); iterator.Next(),
165                                                       ++count) {
166    if (count == 0)
167      EXPECT_EQ(browser(), iterator.browser());
168    else if (count == 1)
169      EXPECT_EQ(browser2.get(), iterator.browser());
170    else if (count == 2)
171      EXPECT_EQ(browser3.get(), iterator.browser());
172    else
173      ADD_FAILURE();
174  }
175
176  // Close all remaining tabs to keep all the destructors happy.
177  browser2->tab_strip_model()->CloseAllTabs();
178  browser3->tab_strip_model()->CloseAllTabs();
179}
180
181#if defined(OS_CHROMEOS)
182// Calling AttemptRestart on ChromeOS will exit the test.
183#define MAYBE_AttemptRestart DISABLED_AttemptRestart
184#else
185#define MAYBE_AttemptRestart AttemptRestart
186#endif
187
188TEST_F(BrowserListTest, MAYBE_AttemptRestart) {
189  ASSERT_TRUE(g_browser_process);
190  TestingPrefServiceSimple testing_pref_service;
191  testing_pref_service.registry()->RegisterBooleanPref(
192      prefs::kWasRestarted, false);
193  testing_pref_service.registry()->RegisterBooleanPref(
194      prefs::kRestartLastSessionOnShutdown,
195      false);
196  testing_pref_service.registry()->RegisterListPref(
197      prefs::kProfilesLastActive);
198
199  TestingBrowserProcess* testing_browser_process =
200      TestingBrowserProcess::GetGlobal();
201  testing_browser_process->SetLocalState(&testing_pref_service);
202  ASSERT_TRUE(g_browser_process->local_state());
203  ProfileManager* profile_manager = new ProfileManager(base::FilePath());
204  testing_browser_process->SetProfileManager(profile_manager);
205
206  chrome::AttemptRestart();
207  // Cancel the effects of us calling chrome::AttemptRestart. Otherwise tests
208  // ran after this one will fail.
209  browser_shutdown::SetTryingToQuit(false);
210
211  EXPECT_TRUE(testing_pref_service.GetBoolean(prefs::kWasRestarted));
212  testing_browser_process->SetLocalState(NULL);
213}
214