summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjcivelli@chromium.org <jcivelli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-14 19:35:10 +0000
committerjcivelli@chromium.org <jcivelli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-14 19:35:10 +0000
commite7f009da9894df2b8e48aa21578aa4e5ecd7a765 (patch)
tree0ca8f38fa2a3531d6f6ef373faac0b1f84eb7369 /chrome/browser
parent286d5d1b43741c2a4b18d4dde38430e5d06097fa (diff)
downloadchromium_src-e7f009da9894df2b8e48aa21578aa4e5ecd7a765.zip
chromium_src-e7f009da9894df2b8e48aa21578aa4e5ecd7a765.tar.gz
chromium_src-e7f009da9894df2b8e48aa21578aa4e5ecd7a765.tar.bz2
Hooking MHTML generation to the browser.
This CL adds a class that can be used to generate MHTML for the current page of a tab. It is not yet surfaced in the UI. BUG=None TEST=Run the browser tests. Review URL: http://codereview.chromium.org/7044095 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89047 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/browser_process.h3
-rw-r--r--chrome/browser/browser_process_impl.cc8
-rw-r--r--chrome/browser/browser_process_impl.h4
-rw-r--r--chrome/browser/download/mhtml_generation_browsertest.cc66
-rw-r--r--chrome/browser/download/mhtml_generation_manager.cc136
-rw-r--r--chrome/browser/download/mhtml_generation_manager.h81
-rw-r--r--chrome/browser/renderer_host/chrome_render_message_filter.cc13
-rw-r--r--chrome/browser/renderer_host/chrome_render_message_filter.h1
8 files changed, 310 insertions, 2 deletions
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index 3351d0b..82e7970 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -30,6 +30,7 @@ class IconManager;
class IntranetRedirectDetector;
class IOThread;
class MetricsService;
+class MHTMLGenerationManager;
class NotificationUIManager;
class PrefService;
class ProfileManager;
@@ -239,6 +240,8 @@ class BrowserProcess {
plugin_data_remover_mime_type_ = mime_type;
}
+ virtual MHTMLGenerationManager* mhtml_generation_manager() = 0;
+
private:
// User-data-dir based profiles.
std::vector<std::wstring> user_data_dir_profiles_;
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 771f67e..41c846c 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -26,6 +26,7 @@
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_protocol_handler.h"
#include "chrome/browser/download/download_file_manager.h"
+#include "chrome/browser/download/mhtml_generation_manager.h"
#include "chrome/browser/download/save_file_manager.h"
#include "chrome/browser/extensions/extension_event_router_forwarder.h"
#include "chrome/browser/extensions/extension_tab_id_map.h"
@@ -691,6 +692,13 @@ prerender::PrerenderTracker* BrowserProcessImpl::prerender_tracker() {
return prerender_tracker_.get();
}
+MHTMLGenerationManager* BrowserProcessImpl::mhtml_generation_manager() {
+ if (!mhtml_generation_manager_.get())
+ mhtml_generation_manager_ = new MHTMLGenerationManager();
+
+ return mhtml_generation_manager_.get();
+}
+
void BrowserProcessImpl::ClearLocalState(const FilePath& profile_path) {
webkit_database::DatabaseTracker::ClearLocalState(profile_path);
BrowsingDataRemover::ClearGearsData(profile_path);
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index 0d32964..adb5a1f 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -116,6 +116,8 @@ class BrowserProcessImpl : public BrowserProcess,
virtual void SetIPCLoggingEnabled(bool enable);
#endif
+ virtual MHTMLGenerationManager* mhtml_generation_manager();
+
private:
void ClearLocalState(const FilePath& profile_path);
bool ShouldClearLocalState(FilePath* profile_path);
@@ -292,6 +294,8 @@ class BrowserProcessImpl : public BrowserProcess,
NotificationRegistrar notification_registrar_;
scoped_refptr<PluginDataRemover> plugin_data_remover_;
+ scoped_refptr<MHTMLGenerationManager> mhtml_generation_manager_;
+
// Monitors the state of the 'DisablePluginFinder' policy.
BooleanPrefMember plugin_finder_disabled_pref_;
diff --git a/chrome/browser/download/mhtml_generation_browsertest.cc b/chrome/browser/download/mhtml_generation_browsertest.cc
new file mode 100644
index 0000000..6077b02
--- /dev/null
+++ b/chrome/browser/download/mhtml_generation_browsertest.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/file_path.h"
+#include "base/scoped_temp_dir.h"
+#include "chrome/browser/download/mhtml_generation_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/testing_browser_process.h"
+#include "chrome/test/ui_test_utils.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "net/test/test_server.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class MHTMLGenerationTest : public InProcessBrowserTest {
+ public:
+ MHTMLGenerationTest() {}
+
+ protected:
+ virtual void SetUp() {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ InProcessBrowserTest::SetUp();
+ }
+
+ ScopedTempDir temp_dir_;
+};
+
+// Tests that generating a MHTML does create contents.
+// Note that the actual content of the file is not tested, the purpose of this
+// test is to ensure we were successfull in creating the MHTML data from the
+// renderer.
+IN_PROC_BROWSER_TEST_F(MHTMLGenerationTest, GenerateMHTML) {
+ ASSERT_TRUE(test_server()->Start());
+
+ FilePath path(temp_dir_.path());
+ path = path.Append(FILE_PATH_LITERAL("test.mht"));
+
+ ui_test_utils::NavigateToURL(browser(),
+ test_server()->GetURL("files/google/google.html"));
+
+ TabContents* tab = browser()->GetSelectedTabContentsWrapper()->tab_contents();
+ MHTMLGenerationManager* mhtml_generation_manager =
+ g_browser_process->mhtml_generation_manager();
+
+ Source<RenderViewHost> source(tab->render_view_host());
+ ui_test_utils::WindowedNotificationObserverWithDetails<
+ MHTMLGenerationManager::NotificationDetails> signal(
+ NotificationType::MHTML_GENERATED, source);
+ mhtml_generation_manager->GenerateMHTML(tab, path);
+ signal.Wait();
+
+ MHTMLGenerationManager::NotificationDetails details;
+ ASSERT_TRUE(signal.GetDetailsFor(source.map_key(), &details));
+ ASSERT_TRUE(details.success);
+
+ // Make sure the generated file has some contents.
+ int64 file_size;
+ ASSERT_TRUE(file_util::GetFileSize(path, &file_size));
+ EXPECT_GT(file_size, 100);
+}
+
+} // namespace
diff --git a/chrome/browser/download/mhtml_generation_manager.cc b/chrome/browser/download/mhtml_generation_manager.cc
new file mode 100644
index 0000000..ea98155
--- /dev/null
+++ b/chrome/browser/download/mhtml_generation_manager.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/download/mhtml_generation_manager.h"
+
+#include "base/platform_file.h"
+#include "chrome/browser/tab_contents/tab_util.h"
+#include "chrome/common/render_messages.h"
+#include "content/browser/renderer_host/render_process_host.h"
+#include "content/browser/renderer_host/render_view_host.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/common/notification_service.h"
+#include "content/common/page_transition_types.h"
+
+MHTMLGenerationManager::Job::Job()
+ : browser_file(base::kInvalidPlatformFileValue),
+ renderer_file(IPC::InvalidPlatformFileForTransit()),
+ process_id(-1),
+ routing_id(-1) {
+}
+
+MHTMLGenerationManager::MHTMLGenerationManager() {
+}
+
+MHTMLGenerationManager::~MHTMLGenerationManager() {
+}
+
+void MHTMLGenerationManager::GenerateMHTML(TabContents* tab_contents,
+ const FilePath& file) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ static int id_counter = 0;
+
+ int job_id = id_counter++;
+ Job job;
+ job.file_path = file;
+ job.process_id = tab_contents->GetRenderProcessHost()->id();
+ job.routing_id = tab_contents->render_view_host()->routing_id();
+ id_to_job_[job_id] = job;
+
+ base::ProcessHandle renderer_process =
+ tab_contents->GetRenderProcessHost()->GetHandle();
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &MHTMLGenerationManager::CreateFile,
+ job_id, file, renderer_process));
+}
+
+void MHTMLGenerationManager::MHTMLGenerated(int job_id, bool success) {
+ JobFinished(job_id, success);
+}
+
+void MHTMLGenerationManager::CreateFile(int job_id, const FilePath& file_path,
+ base::ProcessHandle renderer_process) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ base::PlatformFile browser_file = base::CreatePlatformFile(file_path,
+ base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE,
+ NULL, NULL);
+ if (browser_file == base::kInvalidPlatformFileValue) {
+ LOG(ERROR) << "Failed to create file to save MHTML at: " <<
+ file_path.value();
+ }
+
+ IPC::PlatformFileForTransit renderer_file =
+ IPC::GetFileHandleForProcess(browser_file, renderer_process, false);
+
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &MHTMLGenerationManager::FileCreated,
+ job_id, browser_file, renderer_file));
+}
+
+void MHTMLGenerationManager::FileCreated(int job_id,
+ base::PlatformFile browser_file,
+ IPC::PlatformFileForTransit renderer_file) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (browser_file == base::kInvalidPlatformFileValue) {
+ LOG(ERROR) << "Failed to create file";
+ JobFinished(job_id, false);
+ return;
+ }
+
+ IDToJobMap::iterator iter = id_to_job_.find(job_id);
+ if (iter == id_to_job_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ Job& job = iter->second;
+ job.browser_file = browser_file;
+ job.renderer_file = renderer_file;
+
+ TabContents* tab_contents =
+ tab_util::GetTabContentsByID(job.process_id, job.routing_id);
+ if (!tab_contents) {
+ // The tab went away.
+ JobFinished(job_id, false);
+ return;
+ }
+
+ RenderViewHost* host = tab_contents->render_view_host();
+ host->Send(new ViewMsg_SavePageAsMHTML(host->routing_id(), job_id,
+ renderer_file));
+}
+
+void MHTMLGenerationManager::JobFinished(int job_id, bool success) {
+ IDToJobMap::iterator iter = id_to_job_.find(job_id);
+ if (iter == id_to_job_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ Job& job = iter->second;
+
+ TabContents* tab_contents =
+ tab_util::GetTabContentsByID(job.process_id, job.routing_id);
+ if (tab_contents) {
+ NotificationDetails details;
+ details.file_path = job.file_path;
+ details.success = success;
+
+ NotificationService::current()->Notify(
+ NotificationType::MHTML_GENERATED,
+ Source<RenderViewHost>(tab_contents->render_view_host()),
+ Details<NotificationDetails>(&details));
+ }
+
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &MHTMLGenerationManager::CloseFile,
+ job.browser_file));
+
+ id_to_job_.erase(job_id);
+}
+
+void MHTMLGenerationManager::CloseFile(base::PlatformFile file) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ base::ClosePlatformFile(file);
+}
diff --git a/chrome/browser/download/mhtml_generation_manager.h b/chrome/browser/download/mhtml_generation_manager.h
new file mode 100644
index 0000000..8e8557f
--- /dev/null
+++ b/chrome/browser/download/mhtml_generation_manager.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_DOWNLOAD_MHTML_GENERATION_MANAGER_H_
+#define CHROME_BROWSER_DOWNLOAD_MHTML_GENERATION_MANAGER_H_
+
+#include <map>
+
+#include "base/memory/ref_counted.h"
+#include "base/platform_file.h"
+#include "base/process.h"
+#include "content/browser/browser_thread.h"
+#include "ipc/ipc_platform_file.h"
+
+class FilePath;
+class TabContents;
+
+class MHTMLGenerationManager
+ : public base::RefCountedThreadSafe<MHTMLGenerationManager,
+ BrowserThread::DeleteOnUIThread> {
+ public:
+ MHTMLGenerationManager();
+ ~MHTMLGenerationManager();
+
+ // Instructs the render view to generate a MHTML representation of the current
+ // page for |tab_contents|.
+ void GenerateMHTML(TabContents* tab_contents, const FilePath& file);
+
+ // Notification from the renderer that the MHTML generation succeeded/failed.
+ void MHTMLGenerated(int job_id, bool success);
+
+ // The details sent along with the MHTML_GENERATED notification.
+ struct NotificationDetails {
+ FilePath file_path;
+ bool success;
+ };
+
+ private:
+ struct Job{
+ Job();
+
+ FilePath file_path;
+
+ // The handles to file the MHTML is saved to, for the browser and renderer
+ // processes.
+ base::PlatformFile browser_file;
+ IPC::PlatformFileForTransit renderer_file;
+
+ // The IDs mapping to a specific tab.
+ int process_id;
+ int routing_id;
+ };
+
+ // Called on the file thread to create |file|.
+ void CreateFile(int job_id,
+ const FilePath& file,
+ base::ProcessHandle renderer_process);
+
+ // Called on the UI thread when the file that should hold the MHTML data has
+ // been created. This returns a handle to that file for the browser process
+ // and one for the renderer process. These handles are
+ // kInvalidPlatformFileValue if the file could not be opened.
+ void FileCreated(int job_id,
+ base::PlatformFile browser_file,
+ IPC::PlatformFileForTransit renderer_file);
+
+ // Called on the file thread to close the file the MHTML was saved to.
+ void CloseFile(base::PlatformFile file);
+
+ // Called on the UI thread when a job has been processed (successfully or
+ // not). Closes the file and removes the job from the job map.
+ void JobFinished(int job_id, bool success);
+
+ typedef std::map<int, Job> IDToJobMap;
+ IDToJobMap id_to_job_;
+
+ DISALLOW_COPY_AND_ASSIGN(MHTMLGenerationManager);
+};
+
+#endif // CHROME_BROWSER_DOWNLOAD_MHTML_GENERATION_MANAGER_H_
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc
index d7393aa..15852e2 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
+#include "chrome/browser/download/mhtml_generation_manager.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_message_service.h"
@@ -98,6 +99,7 @@ bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_MESSAGE_HANDLER(ViewHostMsg_CanTriggerClipboardWrite,
OnCanTriggerClipboardWrite)
IPC_MESSAGE_HANDLER(ViewHostMsg_ClearPredictorCache, OnClearPredictorCache)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -137,10 +139,10 @@ void ChromeRenderMessageFilter::OverrideThreadForMessage(
case ExtensionHostMsg_AddListener::ID:
case ExtensionHostMsg_RemoveListener::ID:
case ExtensionHostMsg_CloseChannel::ID:
- *thread = BrowserThread::UI;
- break;
case ViewHostMsg_UpdatedCacheStats::ID:
+ case ViewHostMsg_SavedPageAsMHTML::ID:
*thread = BrowserThread::UI;
+ break;
default:
break;
}
@@ -500,3 +502,10 @@ void ChromeRenderMessageFilter::OnSetCookie(const IPC::Message& message,
AutomationResourceMessageFilter::SetCookiesForUrl(
render_process_id_, message.routing_id(), url, cookie);
}
+
+
+void ChromeRenderMessageFilter::OnSavedPageAsMHTML(int job_id, bool success) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ g_browser_process->mhtml_generation_manager()->
+ MHTMLGenerated(job_id, success);
+}
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.h b/chrome/browser/renderer_host/chrome_render_message_filter.h
index 867b824..55590d2 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.h
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.h
@@ -124,6 +124,7 @@ class ChromeRenderMessageFilter : public BrowserMessageFilter {
const GURL& url,
const GURL& first_party_for_cookies,
const std::string& cookie);
+ void OnSavedPageAsMHTML(int job_id, bool success);
int render_process_id_;
ProfileId profile_id_;