OLD | NEW |
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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "chrome/common/pref_names.h" | 29 #include "chrome/common/pref_names.h" |
30 #include "chrome/test/base/in_process_browser_test.h" | 30 #include "chrome/test/base/in_process_browser_test.h" |
31 #include "chrome/test/base/ui_test_utils.h" | 31 #include "chrome/test/base/ui_test_utils.h" |
32 #include "content/public/browser/browser_context.h" | 32 #include "content/public/browser/browser_context.h" |
33 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
34 #include "content/public/browser/download_item.h" | 34 #include "content/public/browser/download_item.h" |
35 #include "content/public/browser/download_manager.h" | 35 #include "content/public/browser/download_manager.h" |
36 #include "content/public/browser/notification_service.h" | 36 #include "content/public/browser/notification_service.h" |
37 #include "content/public/browser/storage_partition.h" | 37 #include "content/public/browser/storage_partition.h" |
38 #include "content/public/browser/web_contents.h" | 38 #include "content/public/browser/web_contents.h" |
39 #include "content/public/common/content_switches.h" | |
40 #include "content/public/common/page_transition_types.h" | 39 #include "content/public/common/page_transition_types.h" |
41 #include "content/public/test/download_test_observer.h" | 40 #include "content/public/test/download_test_observer.h" |
| 41 #include "content/public/test/test_file_error_injector.h" |
42 #include "content/test/net/url_request_slow_download_job.h" | 42 #include "content/test/net/url_request_slow_download_job.h" |
43 #include "net/base/data_url.h" | 43 #include "net/base/data_url.h" |
44 #include "net/base/net_util.h" | 44 #include "net/base/net_util.h" |
45 #include "net/url_request/url_request.h" | 45 #include "net/url_request/url_request.h" |
46 #include "net/url_request/url_request_context.h" | 46 #include "net/url_request/url_request_context.h" |
47 #include "net/url_request/url_request_job.h" | 47 #include "net/url_request/url_request_job.h" |
48 #include "net/url_request/url_request_job_factory.h" | 48 #include "net/url_request/url_request_job_factory.h" |
49 #include "net/url_request/url_request_job_factory_impl.h" | 49 #include "net/url_request/url_request_job_factory_impl.h" |
50 #include "webkit/blob/blob_data.h" | 50 #include "webkit/blob/blob_data.h" |
51 #include "webkit/blob/blob_storage_controller.h" | 51 #include "webkit/blob/blob_storage_controller.h" |
(...skipping 27 matching lines...) Expand all Loading... |
79 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | 79 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, |
80 content::NotificationService::AllSources()); | 80 content::NotificationService::AllSources()); |
81 } | 81 } |
82 | 82 |
83 virtual ~DownloadsEventsListener() { | 83 virtual ~DownloadsEventsListener() { |
84 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | 84 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, |
85 content::NotificationService::AllSources()); | 85 content::NotificationService::AllSources()); |
86 STLDeleteElements(&events_); | 86 STLDeleteElements(&events_); |
87 } | 87 } |
88 | 88 |
89 void ClearEvents() { | |
90 STLDeleteElements(&events_); | |
91 events_.clear(); | |
92 } | |
93 | |
94 class Event { | 89 class Event { |
95 public: | 90 public: |
96 Event(Profile* profile, | 91 Event(Profile* profile, |
97 const std::string& event_name, | 92 const std::string& event_name, |
98 const std::string& json_args, | 93 const std::string& json_args, |
99 base::Time caught) | 94 base::Time caught) |
100 : profile_(profile), | 95 : profile_(profile), |
101 event_name_(event_name), | 96 event_name_(event_name), |
102 json_args_(json_args), | 97 json_args_(json_args), |
103 args_(base::JSONReader::Read(json_args)), | 98 args_(base::JSONReader::Read(json_args)), |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 return WaitFor(events::kOnDownloadChanged, | 328 return WaitFor(events::kOnDownloadChanged, |
334 base::StringPrintf("[{\"id\": %d," | 329 base::StringPrintf("[{\"id\": %d," |
335 " \"error\": {\"current\": %d}," | 330 " \"error\": {\"current\": %d}," |
336 " \"state\": {" | 331 " \"state\": {" |
337 " \"previous\": \"in_progress\"," | 332 " \"previous\": \"in_progress\"," |
338 " \"current\": \"interrupted\"}}]", | 333 " \"current\": \"interrupted\"}}]", |
339 item->GetId(), | 334 item->GetId(), |
340 expected_error)); | 335 expected_error)); |
341 } | 336 } |
342 | 337 |
343 void ClearEvents() { | |
344 events_listener_->ClearEvents(); | |
345 } | |
346 | |
347 std::string GetExtensionURL() { | 338 std::string GetExtensionURL() { |
348 return extension_->url().spec(); | 339 return extension_->url().spec(); |
349 } | 340 } |
350 std::string GetExtensionId() { | 341 std::string GetExtensionId() { |
351 return extension_->id(); | 342 return extension_->id(); |
352 } | 343 } |
353 | 344 |
354 std::string GetFilename(const char* path) { | 345 std::string GetFilename(const char* path) { |
355 std::string result = | 346 std::string result = |
356 downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe(); | 347 downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe(); |
(...skipping 2741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3098 GetFilename("42 (1).txt.crdownload").c_str(), | 3089 GetFilename("42 (1).txt.crdownload").c_str(), |
3099 GetFilename("42 (1).txt").c_str()))); | 3090 GetFilename("42 (1).txt").c_str()))); |
3100 ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, | 3091 ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, |
3101 base::StringPrintf("[{\"id\": %d," | 3092 base::StringPrintf("[{\"id\": %d," |
3102 " \"state\": {" | 3093 " \"state\": {" |
3103 " \"previous\": \"in_progress\"," | 3094 " \"previous\": \"in_progress\"," |
3104 " \"current\": \"complete\"}}]", | 3095 " \"current\": \"complete\"}}]", |
3105 result_id))); | 3096 result_id))); |
3106 } | 3097 } |
3107 | 3098 |
3108 // TODO(benjhayden) Merge this with the other TestObservers. | 3099 // Test download interruption while extensions determining filename, re-run |
3109 class JustInProgressDownloadObserver | 3100 // through fan-out and fan-in. |
3110 : public content::DownloadTestObserverInProgress { | 3101 // TODO(rdsmith): FILE_OPERATION_INITIALIZE is not right for this test. |
3111 public: | |
3112 JustInProgressDownloadObserver( | |
3113 DownloadManager* download_manager, size_t wait_count) | |
3114 : content::DownloadTestObserverInProgress(download_manager, wait_count) { | |
3115 } | |
3116 | |
3117 virtual ~JustInProgressDownloadObserver() {} | |
3118 | |
3119 private: | |
3120 virtual bool IsDownloadInFinalState(DownloadItem* item) OVERRIDE { | |
3121 return item->GetState() == DownloadItem::IN_PROGRESS; | |
3122 } | |
3123 | |
3124 DISALLOW_COPY_AND_ASSIGN(JustInProgressDownloadObserver); | |
3125 }; | |
3126 | |
3127 // Test download interruption while extensions determining filename. Should not | |
3128 // re-dispatch onDeterminingFilename. | |
3129 #if defined(OS_CHROMEOS) | |
3130 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \ | |
3131 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume | |
3132 #else | |
3133 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \ | |
3134 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume | |
3135 #endif | |
3136 IN_PROC_BROWSER_TEST_F( | 3102 IN_PROC_BROWSER_TEST_F( |
3137 DownloadExtensionTest, | 3103 DownloadExtensionTest, |
3138 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume) { | 3104 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume) { |
3139 CommandLine::ForCurrentProcess()->AppendSwitch( | |
3140 switches::kEnableDownloadResumption); | |
3141 LoadExtension("downloads_split"); | 3105 LoadExtension("downloads_split"); |
3142 CHECK(StartTestServer()); | 3106 CHECK(StartTestServer()); |
| 3107 std::string download_url = test_server()->GetURL("slow?0").spec(); |
3143 GoOnTheRecord(); | 3108 GoOnTheRecord(); |
3144 AddFilenameDeterminer(); | 3109 AddFilenameDeterminer(); |
3145 | 3110 |
| 3111 // TODO Interrupt the download instead of responding to onDeterminingFilename. |
| 3112 scoped_refptr<content::TestFileErrorInjector> injector( |
| 3113 content::TestFileErrorInjector::Create( |
| 3114 GetCurrentManager())); |
| 3115 content::TestFileErrorInjector::FileErrorInfo error_info = { |
| 3116 download_url, |
| 3117 content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE, |
| 3118 0, |
| 3119 content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE}; |
| 3120 injector->AddError(error_info); |
| 3121 injector->InjectErrors(); |
| 3122 |
3146 // Start a download. | 3123 // Start a download. |
3147 DownloadItem* item = NULL; | 3124 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
3148 { | 3125 new DownloadsDownloadFunction(), base::StringPrintf( |
3149 DownloadManager* manager = GetCurrentManager(); | 3126 "[{\"url\": \"%s\"}]", download_url.c_str()))); |
3150 scoped_ptr<content::DownloadTestObserver> observer( | 3127 ASSERT_TRUE(result.get()); |
3151 new JustInProgressDownloadObserver(manager, 1)); | 3128 int result_id = -1; |
3152 ASSERT_EQ(0, manager->InProgressCount()); | 3129 ASSERT_TRUE(result->GetAsInteger(&result_id)); |
3153 // Tabs created just for a download are automatically closed, invalidating | 3130 DownloadItem* item = GetCurrentManager()->GetDownload(result_id); |
3154 // the download's WebContents. Downloads without WebContents cannot be | 3131 ASSERT_TRUE(item); |
3155 // resumed. http://crbug.com/225901 | |
3156 ui_test_utils::NavigateToURLWithDisposition( | |
3157 current_browser(), | |
3158 GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl), | |
3159 CURRENT_TAB, | |
3160 ui_test_utils::BROWSER_TEST_NONE); | |
3161 observer->WaitForFinished(); | |
3162 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); | |
3163 DownloadManager::DownloadVector items; | |
3164 manager->GetAllDownloads(&items); | |
3165 for (DownloadManager::DownloadVector::iterator iter = items.begin(); | |
3166 iter != items.end(); ++iter) { | |
3167 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) { | |
3168 // There should be only one IN_PROGRESS item. | |
3169 EXPECT_EQ(NULL, item); | |
3170 item = *iter; | |
3171 } | |
3172 } | |
3173 ASSERT_TRUE(item); | |
3174 } | |
3175 ScopedCancellingItem canceller(item); | 3132 ScopedCancellingItem canceller(item); |
| 3133 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); |
3176 | 3134 |
3177 // Wait for the onCreated and onDeterminingFilename event. | 3135 // Wait for the onCreated and onDeterminingFilename event. |
3178 ASSERT_TRUE(WaitFor(events::kOnDownloadCreated, | 3136 ASSERT_TRUE(WaitFor(events::kOnDownloadCreated, |
3179 base::StringPrintf("[{\"danger\": \"safe\"," | 3137 base::StringPrintf("[{\"danger\": \"safe\"," |
3180 " \"incognito\": false," | 3138 " \"incognito\": false," |
3181 " \"id\": %d," | 3139 " \"id\": %d," |
3182 " \"mime\": \"application/octet-stream\"," | 3140 " \"mime\": \"text/plain\"," |
3183 " \"paused\": false}]", | 3141 " \"paused\": false," |
3184 item->GetId()))); | 3142 " \"url\": \"%s\"}]", |
| 3143 result_id, |
| 3144 download_url.c_str()))); |
3185 ASSERT_TRUE(WaitFor( | 3145 ASSERT_TRUE(WaitFor( |
3186 events::kOnDownloadDeterminingFilename, | 3146 events::kOnDownloadDeterminingFilename, |
3187 base::StringPrintf("[{\"id\": %d," | 3147 base::StringPrintf("[{\"id\": %d," |
3188 " \"incognito\": false," | 3148 " \"incognito\": false," |
3189 " \"filename\":\"download-unknown-size\"}]", | 3149 " \"filename\":\"slow.txt\"}]", |
3190 item->GetId()))); | 3150 result_id))); |
3191 ASSERT_TRUE(item->GetTargetFilePath().empty()); | 3151 ASSERT_TRUE(item->GetTargetFilePath().empty()); |
3192 ASSERT_TRUE(item->IsInProgress()); | 3152 ASSERT_TRUE(item->IsInProgress()); |
3193 | 3153 |
3194 ClearEvents(); | 3154 ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, |
3195 ui_test_utils::NavigateToURLWithDisposition( | 3155 base::StringPrintf("[{\"id\": %d," |
3196 current_browser(), | 3156 " \"state\": {" |
3197 GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl), | 3157 " \"previous\": \"in_progress\"," |
3198 NEW_BACKGROUND_TAB, | 3158 " \"current\": \"interrupted\"}}]", |
3199 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 3159 result_id))); |
| 3160 ASSERT_TRUE(item->IsInterrupted()); |
| 3161 item->ResumeInterruptedDownload(); |
3200 | 3162 |
3201 // Errors caught before filename determination are delayed until after | 3163 // Wait for and respond to the onDeterminingFilename event. |
3202 // filename determination. | 3164 ASSERT_TRUE(WaitFor( |
| 3165 events::kOnDownloadDeterminingFilename, |
| 3166 base::StringPrintf("[{\"id\": %d," |
| 3167 " \"incognito\": false," |
| 3168 " \"filename\":\"slow.txt\"}]", |
| 3169 result_id))); |
| 3170 ASSERT_TRUE(item->GetTargetFilePath().empty()); |
| 3171 ASSERT_TRUE(item->IsInProgress()); |
3203 std::string error; | 3172 std::string error; |
3204 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename( | 3173 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename( |
3205 current_browser()->profile(), | 3174 current_browser()->profile(), |
3206 false, | 3175 false, |
3207 GetExtensionId(), | 3176 GetExtensionId(), |
3208 item->GetId(), | 3177 result_id, |
3209 base::FilePath(FILE_PATH_LITERAL("42.txt")), | 3178 base::FilePath(FILE_PATH_LITERAL("42.txt")), |
3210 false, | 3179 false, |
3211 &error)) << error; | 3180 &error)); |
3212 EXPECT_EQ("", error); | 3181 EXPECT_EQ("", error); |
3213 | 3182 |
3214 ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, | |
3215 base::StringPrintf("[{\"id\": %d," | |
3216 " \"error\":{\"current\":20}," | |
3217 " \"state\":{" | |
3218 " \"previous\":\"in_progress\"," | |
3219 " \"current\":\"interrupted\"}}]", | |
3220 item->GetId()))); | |
3221 // TODO(benjhayden) These next two lines fail on chromeos. | |
3222 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | |
3223 ASSERT_TRUE(item->IsInterrupted()); | |
3224 | |
3225 ClearEvents(); | |
3226 item->ResumeInterruptedDownload(); | |
3227 | |
3228 // Errors caught before filename determination is complete are delayed until | |
3229 // after filename determination so that, on resumption, filename determination | |
3230 // does not need to be re-done. So, there will not be a second | |
3231 // onDeterminingFilename event. | |
3232 | |
3233 ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, | |
3234 base::StringPrintf("[{\"id\": %d," | |
3235 " \"error\":{\"previous\":20}," | |
3236 " \"state\":{" | |
3237 " \"previous\":\"interrupted\"," | |
3238 " \"current\":\"in_progress\"}}]", | |
3239 item->GetId()))); | |
3240 | |
3241 ClearEvents(); | |
3242 FinishPendingSlowDownloads(); | |
3243 | |
3244 // The download should complete successfully. | 3183 // The download should complete successfully. |
3245 ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, | 3184 ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, |
3246 base::StringPrintf("[{\"id\": %d," | 3185 base::StringPrintf("[{\"id\": %d," |
3247 " \"filename\": {" | 3186 " \"filename\": {" |
3248 " \"previous\": \"%s\"," | 3187 " \"previous\": \"%s\"," |
3249 " \"current\": \"%s\"}," | 3188 " \"current\": \"%s\"}," |
| 3189 " \"state\": {" |
| 3190 " \"previous\": \"in_progress\"," |
| 3191 " \"current\": \"complete\"}}]", |
| 3192 result_id, |
| 3193 GetFilename("42.txt.crdownload").c_str(), |
| 3194 GetFilename("42.txt").c_str()))); |
| 3195 ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, |
| 3196 base::StringPrintf("[{\"id\": %d," |
3250 " \"state\": {" | 3197 " \"state\": {" |
3251 " \"previous\": \"in_progress\"," | 3198 " \"previous\": \"in_progress\"," |
3252 " \"current\": \"complete\"}}]", | 3199 " \"current\": \"complete\"}}]", |
3253 item->GetId(), | 3200 result_id))); |
3254 GetFilename("42.txt.crdownload").c_str(), | |
3255 GetFilename("42.txt").c_str()))); | |
3256 } | 3201 } |
3257 | 3202 |
3258 // TODO(benjhayden) Figure out why DisableExtension() does not fire | 3203 // TODO(benjhayden) Figure out why DisableExtension() does not fire |
3259 // OnListenerRemoved. | 3204 // OnListenerRemoved. |
OLD | NEW |