Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Side by Side Diff: chrome/browser/download/download_browsertest.cc

Issue 1538933002: Enable download resumption by default. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Forgot ChromeOS Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/about_flags.cc ('k') | chrome/browser/download/download_shelf_context_menu.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <sstream> 5 #include <sstream>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/feature_list.h"
10 #include "base/files/file.h" 11 #include "base/files/file.h"
11 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
12 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h" 14 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
15 #include "base/path_service.h" 16 #include "base/path_service.h"
16 #include "base/prefs/pref_service.h" 17 #include "base/prefs/pref_service.h"
17 #include "base/stl_util.h" 18 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_split.h" 20 #include "base/strings/string_split.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #include "content/public/browser/download_item.h" 74 #include "content/public/browser/download_item.h"
74 #include "content/public/browser/download_manager.h" 75 #include "content/public/browser/download_manager.h"
75 #include "content/public/browser/download_save_info.h" 76 #include "content/public/browser/download_save_info.h"
76 #include "content/public/browser/download_url_parameters.h" 77 #include "content/public/browser/download_url_parameters.h"
77 #include "content/public/browser/notification_source.h" 78 #include "content/public/browser/notification_source.h"
78 #include "content/public/browser/render_frame_host.h" 79 #include "content/public/browser/render_frame_host.h"
79 #include "content/public/browser/render_view_host.h" 80 #include "content/public/browser/render_view_host.h"
80 #include "content/public/browser/render_widget_host.h" 81 #include "content/public/browser/render_widget_host.h"
81 #include "content/public/browser/resource_context.h" 82 #include "content/public/browser/resource_context.h"
82 #include "content/public/browser/web_contents.h" 83 #include "content/public/browser/web_contents.h"
84 #include "content/public/common/content_features.h"
83 #include "content/public/common/content_switches.h" 85 #include "content/public/common/content_switches.h"
84 #include "content/public/common/context_menu_params.h" 86 #include "content/public/common/context_menu_params.h"
85 #include "content/public/test/browser_test_utils.h" 87 #include "content/public/test/browser_test_utils.h"
86 #include "content/public/test/download_test_observer.h" 88 #include "content/public/test/download_test_observer.h"
87 #include "content/public/test/test_file_error_injector.h" 89 #include "content/public/test/test_file_error_injector.h"
88 #include "content/public/test/test_navigation_observer.h" 90 #include "content/public/test/test_navigation_observer.h"
89 #include "extensions/browser/extension_dialog_auto_confirm.h" 91 #include "extensions/browser/extension_dialog_auto_confirm.h"
90 #include "extensions/browser/extension_system.h" 92 #include "extensions/browser/extension_system.h"
91 #include "extensions/common/feature_switch.h" 93 #include "extensions/common/feature_switch.h"
92 #include "net/base/filename_util.h" 94 #include "net/base/filename_util.h"
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 }; 402 };
401 403
402 struct FileErrorInjectInfo { 404 struct FileErrorInjectInfo {
403 DownloadInfo download_info; 405 DownloadInfo download_info;
404 content::TestFileErrorInjector::FileErrorInfo error_info; 406 content::TestFileErrorInjector::FileErrorInfo error_info;
405 }; 407 };
406 408
407 DownloadTest() {} 409 DownloadTest() {}
408 410
409 void SetUpOnMainThread() override { 411 void SetUpOnMainThread() override {
412 base::FeatureList::ClearInstanceForTesting();
413 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList);
414 feature_list->InitializeFromCommandLine(
415 features::kDownloadResumption.name, std::string());
416 base::FeatureList::SetInstance(std::move(feature_list));
410 BrowserThread::PostTask( 417 BrowserThread::PostTask(
411 BrowserThread::IO, FROM_HERE, 418 BrowserThread::IO, FROM_HERE,
412 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); 419 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
413 ASSERT_TRUE(InitialSetup()); 420 ASSERT_TRUE(InitialSetup());
414 } 421 }
415 422
416 void TearDownOnMainThread() override { 423 void TearDownOnMainThread() override {
417 // Needs to be torn down on the main thread. file_activity_observer_ holds a 424 // Needs to be torn down on the main thread. file_activity_observer_ holds a
418 // reference to the ChromeDownloadManagerDelegate which should be destroyed 425 // reference to the ChromeDownloadManagerDelegate which should be destroyed
419 // on the UI thread. 426 // on the UI thread.
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 std::string server_path = "/downloads/"; 844 std::string server_path = "/downloads/";
838 server_path += download_info.url_name; 845 server_path += download_info.url_name;
839 GURL url = embedded_test_server()->GetURL(server_path); 846 GURL url = embedded_test_server()->GetURL(server_path);
840 ASSERT_TRUE(url.is_valid()); 847 ASSERT_TRUE(url.is_valid());
841 848
842 DownloadManager* download_manager = DownloadManagerForBrowser(browser()); 849 DownloadManager* download_manager = DownloadManagerForBrowser(browser());
843 WebContents* web_contents = 850 WebContents* web_contents =
844 browser()->tab_strip_model()->GetActiveWebContents(); 851 browser()->tab_strip_model()->GetActiveWebContents();
845 ASSERT_TRUE(web_contents); 852 ASSERT_TRUE(web_contents);
846 853
847 scoped_ptr<content::DownloadTestObserver> observer( 854 scoped_ptr<content::DownloadTestObserver> observer;
848 new content::DownloadTestObserverTerminal( 855 if (download_info.reason == content::DOWNLOAD_INTERRUPT_REASON_NONE) {
849 download_manager, 856 observer.reset(new content::DownloadTestObserverTerminal(
850 1, 857 download_manager, 1,
851 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL)); 858 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
859 } else {
860 observer.reset(new content::DownloadTestObserverInterrupted(
861 download_manager, 1,
862 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
863 }
852 864
853 if (download_info.download_method == DOWNLOAD_DIRECT) { 865 if (download_info.download_method == DOWNLOAD_DIRECT) {
854 // Go directly to download. Don't wait for navigation. 866 // Go directly to download. Don't wait for navigation.
855 scoped_refptr<content::DownloadTestItemCreationObserver> 867 scoped_refptr<content::DownloadTestItemCreationObserver>
856 creation_observer(new content::DownloadTestItemCreationObserver); 868 creation_observer(new content::DownloadTestItemCreationObserver);
857 869
858 scoped_ptr<DownloadUrlParameters> params( 870 scoped_ptr<DownloadUrlParameters> params(
859 DownloadUrlParameters::FromWebContents(web_contents, url)); 871 DownloadUrlParameters::FromWebContents(web_contents, url));
860 params->set_callback(creation_observer->callback()); 872 params->set_callback(creation_observer->callback());
861 DownloadManagerForBrowser(browser())->DownloadUrl(params.Pass()); 873 DownloadManagerForBrowser(browser())->DownloadUrl(params.Pass());
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 EXPECT_EQ(net::URLRequestSlowDownloadJob::kFirstDownloadSize 1696 EXPECT_EQ(net::URLRequestSlowDownloadJob::kFirstDownloadSize
1685 + net::URLRequestSlowDownloadJob::kSecondDownloadSize, 1697 + net::URLRequestSlowDownloadJob::kSecondDownloadSize,
1686 row.total_bytes); 1698 row.total_bytes);
1687 EXPECT_EQ(history::DownloadState::IN_PROGRESS, row.state); 1699 EXPECT_EQ(history::DownloadState::IN_PROGRESS, row.state);
1688 EXPECT_FALSE(row.opened); 1700 EXPECT_FALSE(row.opened);
1689 1701
1690 // Finish the download. We're ok relying on the history to be flushed 1702 // Finish the download. We're ok relying on the history to be flushed
1691 // at this point as our queries will be behind the history updates 1703 // at this point as our queries will be behind the history updates
1692 // invoked by completion. 1704 // invoked by completion.
1693 scoped_ptr<content::DownloadTestObserver> download_observer( 1705 scoped_ptr<content::DownloadTestObserver> download_observer(
1694 CreateWaiter(browser(), 1)); 1706 new content::DownloadTestObserverInterrupted(
1695 ui_test_utils::NavigateToURL(browser(), 1707 DownloadManagerForBrowser(browser()), 1,
1696 GURL(net::URLRequestSlowDownloadJob::kErrorDownloadUrl)); 1708 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
1709 ui_test_utils::NavigateToURL(
1710 browser(), GURL(net::URLRequestSlowDownloadJob::kErrorDownloadUrl));
1697 download_observer->WaitForFinished(); 1711 download_observer->WaitForFinished();
1698 EXPECT_EQ(1u, download_observer->NumDownloadsSeenInState( 1712 EXPECT_EQ(1u, download_observer->NumDownloadsSeenInState(
1699 DownloadItem::INTERRUPTED)); 1713 DownloadItem::INTERRUPTED));
1700 base::Time end(base::Time::Now()); 1714 base::Time end(base::Time::Now());
1701 1715
1702 // Get what was stored in the history. 1716 // Get what was stored in the history.
1703 ASSERT_TRUE(DownloadsHistoryDataCollector( 1717 ASSERT_TRUE(DownloadsHistoryDataCollector(
1704 browser()->profile()).WaitForDownloadInfo(&downloads_in_database)); 1718 browser()->profile()).WaitForDownloadInfo(&downloads_in_database));
1705 ASSERT_EQ(1u, downloads_in_database->size()); 1719 ASSERT_EQ(1u, downloads_in_database->size());
1706 1720
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after
3011 ASSERT_TRUE(base::GetFileSize( 3025 ASSERT_TRUE(base::GetFileSize(
3012 download_items[0]->GetTargetFilePath(), &downloaded_size)); 3026 download_items[0]->GetTargetFilePath(), &downloaded_size));
3013 ASSERT_EQ(size + 1, downloaded_size); 3027 ASSERT_EQ(size + 1, downloaded_size);
3014 ASSERT_TRUE(base::DieFileDie(file_path, false)); 3028 ASSERT_TRUE(base::DieFileDie(file_path, false));
3015 ASSERT_TRUE(base::DieFileDie(download_items[0]->GetTargetFilePath(), false)); 3029 ASSERT_TRUE(base::DieFileDie(download_items[0]->GetTargetFilePath(), false));
3016 } 3030 }
3017 3031
3018 // A download that is interrupted due to a file error should be able to be 3032 // A download that is interrupted due to a file error should be able to be
3019 // resumed. 3033 // resumed.
3020 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_NoPrompt) { 3034 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_NoPrompt) {
3021 base::CommandLine::ForCurrentProcess()->AppendSwitch(
3022 switches::kEnableDownloadResumption);
3023 scoped_refptr<content::TestFileErrorInjector> error_injector( 3035 scoped_refptr<content::TestFileErrorInjector> error_injector(
3024 content::TestFileErrorInjector::Create( 3036 content::TestFileErrorInjector::Create(
3025 DownloadManagerForBrowser(browser()))); 3037 DownloadManagerForBrowser(browser())));
3026 scoped_ptr<content::DownloadTestObserver> completion_observer( 3038 scoped_ptr<content::DownloadTestObserver> completion_observer(
3027 CreateWaiter(browser(), 1)); 3039 CreateWaiter(browser(), 1));
3028 EnableFileChooser(true); 3040 EnableFileChooser(true);
3029 3041
3030 DownloadItem* download = StartMockDownloadAndInjectError( 3042 DownloadItem* download = StartMockDownloadAndInjectError(
3031 error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 3043 error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
3032 ASSERT_TRUE(download); 3044 ASSERT_TRUE(download);
3033 3045
3034 download->Resume(); 3046 download->Resume();
3035 completion_observer->WaitForFinished(); 3047 completion_observer->WaitForFinished();
3036 3048
3037 EXPECT_EQ( 3049 EXPECT_EQ(
3038 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); 3050 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
3039 EXPECT_FALSE(DidShowFileChooser()); 3051 EXPECT_FALSE(DidShowFileChooser());
3040 } 3052 }
3041 3053
3042 // A download that's interrupted due to a reason that indicates that the target 3054 // A download that's interrupted due to a reason that indicates that the target
3043 // path is invalid or unusable should cause a prompt to be displayed on 3055 // path is invalid or unusable should cause a prompt to be displayed on
3044 // resumption. 3056 // resumption.
3045 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPrompt) { 3057 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPrompt) {
3046 base::CommandLine::ForCurrentProcess()->AppendSwitch(
3047 switches::kEnableDownloadResumption);
3048 scoped_refptr<content::TestFileErrorInjector> error_injector( 3058 scoped_refptr<content::TestFileErrorInjector> error_injector(
3049 content::TestFileErrorInjector::Create( 3059 content::TestFileErrorInjector::Create(
3050 DownloadManagerForBrowser(browser()))); 3060 DownloadManagerForBrowser(browser())));
3051 scoped_ptr<content::DownloadTestObserver> completion_observer( 3061 scoped_ptr<content::DownloadTestObserver> completion_observer(
3052 CreateWaiter(browser(), 1)); 3062 CreateWaiter(browser(), 1));
3053 EnableFileChooser(true); 3063 EnableFileChooser(true);
3054 3064
3055 DownloadItem* download = StartMockDownloadAndInjectError( 3065 DownloadItem* download = StartMockDownloadAndInjectError(
3056 error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE); 3066 error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE);
3057 ASSERT_TRUE(download); 3067 ASSERT_TRUE(download);
3058 3068
3059 download->Resume(); 3069 download->Resume();
3060 completion_observer->WaitForFinished(); 3070 completion_observer->WaitForFinished();
3061 3071
3062 EXPECT_EQ( 3072 EXPECT_EQ(
3063 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); 3073 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
3064 EXPECT_TRUE(DidShowFileChooser()); 3074 EXPECT_TRUE(DidShowFileChooser());
3065 } 3075 }
3066 3076
3067 // The user shouldn't be prompted on a resumed download unless a prompt is 3077 // The user shouldn't be prompted on a resumed download unless a prompt is
3068 // necessary due to the interrupt reason. 3078 // necessary due to the interrupt reason.
3069 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPromptAlways) { 3079 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPromptAlways) {
3070 base::CommandLine::ForCurrentProcess()->AppendSwitch(
3071 switches::kEnableDownloadResumption);
3072 browser()->profile()->GetPrefs()->SetBoolean( 3080 browser()->profile()->GetPrefs()->SetBoolean(
3073 prefs::kPromptForDownload, true); 3081 prefs::kPromptForDownload, true);
3074 scoped_refptr<content::TestFileErrorInjector> error_injector( 3082 scoped_refptr<content::TestFileErrorInjector> error_injector(
3075 content::TestFileErrorInjector::Create( 3083 content::TestFileErrorInjector::Create(
3076 DownloadManagerForBrowser(browser()))); 3084 DownloadManagerForBrowser(browser())));
3077 scoped_ptr<content::DownloadTestObserver> completion_observer( 3085 scoped_ptr<content::DownloadTestObserver> completion_observer(
3078 CreateWaiter(browser(), 1)); 3086 CreateWaiter(browser(), 1));
3079 EnableFileChooser(true); 3087 EnableFileChooser(true);
3080 3088
3081 DownloadItem* download = StartMockDownloadAndInjectError( 3089 DownloadItem* download = StartMockDownloadAndInjectError(
3082 error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 3090 error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
3083 ASSERT_TRUE(download); 3091 ASSERT_TRUE(download);
3084 3092
3085 // Prompts the user initially because of the kPromptForDownload preference. 3093 // Prompts the user initially because of the kPromptForDownload preference.
3086 EXPECT_TRUE(DidShowFileChooser()); 3094 EXPECT_TRUE(DidShowFileChooser());
3087 3095
3088 download->Resume(); 3096 download->Resume();
3089 completion_observer->WaitForFinished(); 3097 completion_observer->WaitForFinished();
3090 3098
3091 EXPECT_EQ( 3099 EXPECT_EQ(
3092 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); 3100 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
3093 // Shouldn't prompt for resumption. 3101 // Shouldn't prompt for resumption.
3094 EXPECT_FALSE(DidShowFileChooser()); 3102 EXPECT_FALSE(DidShowFileChooser());
3095 } 3103 }
3096 3104
3097 // A download that is interrupted due to a transient error should be resumed 3105 // A download that is interrupted due to a transient error should be resumed
3098 // automatically. 3106 // automatically.
3099 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_Automatic) { 3107 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_Automatic) {
3100 base::CommandLine::ForCurrentProcess()->AppendSwitch(
3101 switches::kEnableDownloadResumption);
3102 scoped_refptr<content::TestFileErrorInjector> error_injector( 3108 scoped_refptr<content::TestFileErrorInjector> error_injector(
3103 content::TestFileErrorInjector::Create( 3109 content::TestFileErrorInjector::Create(
3104 DownloadManagerForBrowser(browser()))); 3110 DownloadManagerForBrowser(browser())));
3105 3111
3106 DownloadItem* download = StartMockDownloadAndInjectError( 3112 DownloadItem* download = StartMockDownloadAndInjectError(
3107 error_injector.get(), 3113 error_injector.get(),
3108 content::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); 3114 content::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
3109 ASSERT_TRUE(download); 3115 ASSERT_TRUE(download);
3110 3116
3111 // The number of times this the download is resumed automatically is defined 3117 // The number of times this the download is resumed automatically is defined
3112 // in DownloadItemImpl::kMaxAutoResumeAttempts. The number of DownloadFiles 3118 // in DownloadItemImpl::kMaxAutoResumeAttempts. The number of DownloadFiles
3113 // created should be that number + 1 (for the original download request). We 3119 // created should be that number + 1 (for the original download request). We
3114 // only care that it is greater than 1. 3120 // only care that it is greater than 1.
3115 EXPECT_GT(1u, error_injector->TotalFileCount()); 3121 EXPECT_GT(1u, error_injector->TotalFileCount());
3116 } 3122 }
3117 3123
3118 // An interrupting download should be resumable multiple times. 3124 // An interrupting download should be resumable multiple times.
3119 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_MultipleAttempts) { 3125 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_MultipleAttempts) {
3120 base::CommandLine::ForCurrentProcess()->AppendSwitch(
3121 switches::kEnableDownloadResumption);
3122 scoped_refptr<content::TestFileErrorInjector> error_injector( 3126 scoped_refptr<content::TestFileErrorInjector> error_injector(
3123 content::TestFileErrorInjector::Create( 3127 content::TestFileErrorInjector::Create(
3124 DownloadManagerForBrowser(browser()))); 3128 DownloadManagerForBrowser(browser())));
3125 scoped_ptr<DownloadTestObserverNotInProgress> completion_observer( 3129 scoped_ptr<DownloadTestObserverNotInProgress> completion_observer(
3126 new DownloadTestObserverNotInProgress( 3130 new DownloadTestObserverNotInProgress(
3127 DownloadManagerForBrowser(browser()), 1)); 3131 DownloadManagerForBrowser(browser()), 1));
3128 // Wait for two transitions to a resumable state 3132 // Wait for two transitions to a resumable state
3129 scoped_ptr<content::DownloadTestObserver> resumable_observer( 3133 scoped_ptr<content::DownloadTestObserver> resumable_observer(
3130 new DownloadTestObserverResumable( 3134 new DownloadTestObserverResumable(
3131 DownloadManagerForBrowser(browser()), 2)); 3135 DownloadManagerForBrowser(browser()), 2));
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
3619 3623
3620 scoped_ptr<content::DownloadTestObserver> observer(DangerousDownloadWaiter( 3624 scoped_ptr<content::DownloadTestObserver> observer(DangerousDownloadWaiter(
3621 browser(), 1, content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_DENY)); 3625 browser(), 1, content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_DENY));
3622 ui_test_utils::NavigateToURL(browser(), extension_url); 3626 ui_test_utils::NavigateToURL(browser(), extension_url);
3623 3627
3624 observer->WaitForFinished(); 3628 observer->WaitForFinished();
3625 3629
3626 // Download shelf should close. 3630 // Download shelf should close.
3627 EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible()); 3631 EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
3628 } 3632 }
OLDNEW
« no previous file with comments | « chrome/browser/about_flags.cc ('k') | chrome/browser/download/download_shelf_context_menu.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698