1 // Copyright 2015 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.
5 #include "base/logging.h"
6 #include "base/strings/stringprintf.h"
7 #include "chrome/browser/download/chrome_download_manager_delegate.h"
8 #include "chrome/browser/download/download_service.h"
9 #include "chrome/browser/download/download_service_factory.h"
10 #include "chrome/browser/profiles/profile_manager.h"
11 #include "chrome/test/base/test_browser_window.h"
12 #include "chrome/test/base/testing_browser_process.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "chrome/test/base/testing_profile_manager.h"
15 #include "components/keyed_service/core/keyed_service.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 class TestingDownloadService
: public DownloadService
{
22 TestingDownloadService() : download_count_(0) {}
23 ~TestingDownloadService() override
{}
25 // All methods that aren't expected to be called in the execution of
26 // this unit test are marked to result in test failure. Using a simple
27 // mock for this class should be re-evaluated if any of these
28 // methods are being called; it may mean that a more fully featured
29 // DownloadService implementation is needed.
31 void SetDownloadCount(int download_count
) {
32 download_count_
= download_count
;
36 ChromeDownloadManagerDelegate
* GetDownloadManagerDelegate() override
{
41 DownloadHistory
* GetDownloadHistory() override
{
46 #if defined(ENABLE_EXTENSIONS)
47 extensions::ExtensionDownloadsEventRouter
* GetExtensionEventRouter()
53 bool HasCreatedDownloadManager() override
{ return true; }
55 int NonMaliciousDownloadCount() const override
{ return download_count_
; }
57 void CancelDownloads() override
{}
59 void SetDownloadManagerDelegateForTesting(
60 scoped_ptr
<ChromeDownloadManagerDelegate
> delegate
) override
{
64 bool IsShelfEnabled() override
{
69 void Shutdown() override
{}
74 DISALLOW_COPY_AND_ASSIGN(TestingDownloadService
);
77 static scoped_ptr
<KeyedService
> CreateTestingDownloadService(
78 content::BrowserContext
* browser_context
) {
79 return scoped_ptr
<KeyedService
>(new TestingDownloadService());
82 class BrowserCloseTest
: public testing::Test
{
85 : profile_manager_(TestingBrowserProcess::GetGlobal()), name_index_(0) {}
87 ~BrowserCloseTest() override
{}
89 void SetUp() override
{ ASSERT_TRUE(profile_manager_
.SetUp()); }
91 void TearDown() override
{
92 for (auto& browser_window_pair
: browser_windows_
) {
93 while (!browser_window_pair
.second
.empty()) {
94 TestBrowserWindow
* window
= browser_window_pair
.second
.back();
95 browser_window_pair
.second
.pop_back();
99 for (auto& browser_pair
: browsers_
) {
100 while (!browser_pair
.second
.empty()) {
101 Browser
* browser
= browser_pair
.second
.back();
102 browser_pair
.second
.pop_back();
108 // Create a profile with the specified number of windows and downloads
109 // associated with it.
110 Profile
* CreateProfile(int windows
, int downloads
) {
111 std::string
name(base::StringPrintf("Profile_%d", ++name_index_
));
112 TestingProfile
* profile
= profile_manager_
.CreateTestingProfile(name
);
114 ConfigureCreatedProfile(profile
, windows
, downloads
);
119 Profile
* CreateIncognitoProfile(Profile
* profile
,
122 Profile
* otr_profile
= profile
->GetOffTheRecordProfile();
124 ConfigureCreatedProfile(otr_profile
, windows
, downloads
);
129 Browser
* GetProfileBrowser(Profile
* profile
, int index
) {
130 CHECK(browsers_
.end() != browsers_
.find(profile
));
131 CHECK_GT(browsers_
[profile
].size(), static_cast<size_t>(index
));
133 return browsers_
[profile
][index
];
137 void ConfigureCreatedProfile(Profile
* profile
,
140 DownloadServiceFactory::GetInstance()->SetTestingFactory(
141 profile
, &CreateTestingDownloadService
);
142 DownloadService
* download_service(
143 DownloadServiceFactory::GetForBrowserContext(profile
));
144 TestingDownloadService
* mock_download_service(
145 static_cast<TestingDownloadService
*>(download_service
));
146 mock_download_service
->SetDownloadCount(num_downloads
);
148 CHECK(browser_windows_
.end() == browser_windows_
.find(profile
));
149 CHECK(browsers_
.end() == browsers_
.find(profile
));
151 std::vector
<TestBrowserWindow
*> windows
;
152 std::vector
<Browser
*> browsers
;
153 for (int i
= 0; i
< num_windows
; ++i
) {
154 TestBrowserWindow
* window
= new TestBrowserWindow();
155 Browser::CreateParams
params(profile
, chrome::HOST_DESKTOP_TYPE_FIRST
);
156 params
.type
= Browser::TYPE_TABBED
;
157 params
.window
= window
;
158 Browser
* browser
= new Browser(params
);
160 windows
.push_back(window
);
161 browsers
.push_back(browser
);
164 browser_windows_
[profile
] = windows
;
165 browsers_
[profile
] = browsers
;
168 // Note that the vector elements are all owned by this class and must be
170 std::map
<Profile
*, std::vector
<TestBrowserWindow
*>> browser_windows_
;
171 std::map
<Profile
*, std::vector
<Browser
*>> browsers_
;
173 content::TestBrowserThreadBundle thread_bundle_
;
174 TestingProfileManager profile_manager_
;
178 // Last window close (incognito window) will trigger warning.
179 TEST_F(BrowserCloseTest
, LastWindowIncognito
) {
180 Profile
* profile
= CreateProfile(0, 0);
181 Profile
* incognito_profile
= CreateIncognitoProfile(profile
, 1, 1);
182 Browser
* browser
= GetProfileBrowser(incognito_profile
, 0);
184 int num_downloads_blocking
= 0;
185 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN
,
186 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
187 EXPECT_EQ(num_downloads_blocking
, 1);
190 // Last incognito window close triggers incognito warning.
191 TEST_F(BrowserCloseTest
, LastIncognito
) {
192 Profile
* profile
= CreateProfile(1, 0);
193 Profile
* incognito_profile
= CreateIncognitoProfile(profile
, 1, 1);
194 Browser
* browser(GetProfileBrowser(incognito_profile
, 0));
196 int num_downloads_blocking
= 0;
197 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE
,
198 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
199 EXPECT_EQ(num_downloads_blocking
, 1);
202 // Last incognito window close with no downloads => no warning.
203 TEST_F(BrowserCloseTest
, LastIncognitoNoDownloads
) {
204 Profile
* profile
= CreateProfile(0, 0);
205 Profile
* incognito_profile
= CreateIncognitoProfile(profile
, 1, 0);
206 Browser
* browser
= GetProfileBrowser(incognito_profile
, 0);
208 int num_downloads_blocking
= 0;
209 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK
,
210 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
213 // Last incognito window with window+download on another incognito profile
215 TEST_F(BrowserCloseTest
, NoIncognitoCrossChat
) {
216 Profile
* profile1
= CreateProfile(0, 0);
217 Profile
* incognito_profile1
= CreateIncognitoProfile(profile1
, 1, 0);
218 Profile
* profile2
= CreateProfile(0, 0);
219 CreateIncognitoProfile(profile2
, 1, 1);
221 Browser
* browser
= GetProfileBrowser(incognito_profile1
, 0);
223 int num_downloads_blocking
= 0;
224 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK
,
225 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
228 // Non-last incognito window => no warning.
229 TEST_F(BrowserCloseTest
, NonLastIncognito
) {
230 Profile
* profile
= CreateProfile(0, 0);
231 Profile
* incognito_profile
= CreateIncognitoProfile(profile
, 2, 1);
232 Browser
* browser
= GetProfileBrowser(incognito_profile
, 0);
234 int num_downloads_blocking
= 0;
235 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK
,
236 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
239 // Non-last regular window => no warning.
240 TEST_F(BrowserCloseTest
, NonLastRegular
) {
241 Profile
* profile
= CreateProfile(2, 1);
242 Browser
* browser
= GetProfileBrowser(profile
, 0);
244 int num_downloads_blocking
= 0;
245 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK
,
246 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
249 // Last regular window triggers browser close warning.
250 TEST_F(BrowserCloseTest
, LastRegular
) {
251 Profile
* profile
= CreateProfile(1, 1);
252 Browser
* browser
= GetProfileBrowser(profile
, 0);
254 int num_downloads_blocking
= 0;
255 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN
,
256 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
257 EXPECT_EQ(num_downloads_blocking
, 1);
260 // Last regular window triggers browser close warning if download is on a
261 // different profile.
262 TEST_F(BrowserCloseTest
, LastRegularDifferentProfile
) {
263 Profile
* profile1
= CreateProfile(1, 0);
266 Browser
* browser
= GetProfileBrowser(profile1
, 0);
268 int num_downloads_blocking
= 0;
269 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN
,
270 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
271 EXPECT_EQ(num_downloads_blocking
, 1);
274 // Last regular + incognito window + download => no warning.
275 TEST_F(BrowserCloseTest
, LastRegularPlusIncognito
) {
276 Profile
* profile
= CreateProfile(1, 0);
277 CreateIncognitoProfile(profile
, 1, 1);
279 Browser
* browser
= GetProfileBrowser(profile
, 0);
281 int num_downloads_blocking
= 0;
282 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK
,
283 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
286 // Last regular window + window on other profile => no warning.
287 TEST_F(BrowserCloseTest
, LastRegularPlusOtherProfile
) {
288 Profile
* profile
= CreateProfile(1, 1);
291 Browser
* browser
= GetProfileBrowser(profile
, 0);
293 int num_downloads_blocking
= 0;
294 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK
,
295 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
298 // Last regular window + window on other incognito profile => no warning.
299 TEST_F(BrowserCloseTest
, LastRegularPlusOtherIncognito
) {
300 Profile
* profile1
= CreateProfile(1, 0);
301 Profile
* profile2
= CreateProfile(0, 0);
302 CreateIncognitoProfile(profile2
, 1, 1);
304 Browser
* browser
= GetProfileBrowser(profile1
, 0);
306 int num_downloads_blocking
= 0;
307 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK
,
308 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
311 // Last regular + download + incognito window => no warning.
312 TEST_F(BrowserCloseTest
, LastRegularPlusIncognito2
) {
313 Profile
* profile
= CreateProfile(1, 1);
314 CreateIncognitoProfile(profile
, 1, 0);
316 Browser
* browser
= GetProfileBrowser(profile
, 0);
318 int num_downloads_blocking
= 0;
319 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK
,
320 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
323 // Multiple downloads are recognized.
324 TEST_F(BrowserCloseTest
, Plural
) {
325 Profile
* profile
= CreateProfile(1, 2);
327 Browser
* browser
= GetProfileBrowser(profile
, 0);
329 int num_downloads_blocking
= 0;
330 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN
,
331 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
332 EXPECT_EQ(2, num_downloads_blocking
);
335 // Multiple downloads are recognized for incognito.
336 TEST_F(BrowserCloseTest
, PluralIncognito
) {
337 Profile
* profile
= CreateProfile(1, 0);
338 Profile
* incognito_profile
= CreateIncognitoProfile(profile
, 1, 2);
340 Browser
* browser
= GetProfileBrowser(incognito_profile
, 0);
342 int num_downloads_blocking
= 0;
343 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE
,
344 browser
->OkToCloseWithInProgressDownloads(&num_downloads_blocking
));
345 EXPECT_EQ(2, num_downloads_blocking
);