summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc4
-rw-r--r--chrome/browser/extensions/extension_save_page_api.cc133
-rw-r--r--chrome/browser/extensions/extension_save_page_api.h45
-rw-r--r--chrome/browser/extensions/extension_save_page_apitest.cc30
4 files changed, 212 insertions, 0 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 63791ab..74341d0 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -39,6 +39,7 @@
#include "chrome/browser/extensions/extension_processes_api.h"
#include "chrome/browser/extensions/extension_proxy_api.h"
#include "chrome/browser/extensions/extension_rlz_module.h"
+#include "chrome/browser/extensions/extension_save_page_api.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_settings_api.h"
#include "chrome/browser/extensions/extension_sidebar_api.h"
@@ -448,6 +449,9 @@ void FactoryRegistry::ResetFunctions() {
RegisterFunction<DownloadsAcceptDangerFunction>();
RegisterFunction<DownloadsShowFunction>();
RegisterFunction<DownloadsDragFunction>();
+
+ // SavePage
+ RegisterFunction<SavePageAsMHTMLFunction>();
}
void FactoryRegistry::GetAllNames(std::vector<std::string>* names) {
diff --git a/chrome/browser/extensions/extension_save_page_api.cc b/chrome/browser/extensions/extension_save_page_api.cc
new file mode 100644
index 0000000..2aee2ce
--- /dev/null
+++ b/chrome/browser/extensions/extension_save_page_api.cc
@@ -0,0 +1,133 @@
+// 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/extensions/extension_save_page_api.h"
+
+#include "base/file_util.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_tabs_module.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "content/browser/child_process_security_policy.h"
+#include "content/browser/renderer_host/render_view_host.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/browser/download/mhtml_generation_manager.h"
+#include "content/common/content_notification_types.h"
+#include "content/common/notification_service.h"
+
+// Error messages.
+const char* const kFileTooBigError = "The MHTML file generated is too big.";
+const char* const kMHTMLGenerationFailedError = "Failed to generate MHTML.";
+const char* const kSizeRetrievalError =
+ "Failed to retrieve size of generated MHTML.";
+const char* const kTemporaryFileError = "Failed to create a temporary file.";
+const char* const kTabClosedError = "Cannot find the tab for thie request.";
+
+SavePageAsMHTMLFunction::SavePageAsMHTMLFunction() : tab_id_(0) {
+}
+
+SavePageAsMHTMLFunction::~SavePageAsMHTMLFunction() {
+}
+
+bool SavePageAsMHTMLFunction::RunImpl() {
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id_));
+
+ AddRef(); // Balanced in ReturnFailure/ReturnSuccess()
+
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &SavePageAsMHTMLFunction::CreateTemporaryFile));
+ return true;
+}
+
+void SavePageAsMHTMLFunction::CreateTemporaryFile() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ // TODO(jcivelli): http://crbug.com/97489 we don't clean-up the temporary file
+ // at this point. It must be done before we can take that API
+ // out of experimental.
+ bool success = file_util::CreateTemporaryFile(&mhtml_path_);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &SavePageAsMHTMLFunction::TemporaryFileCreated,
+ success));
+}
+
+void SavePageAsMHTMLFunction::TemporaryFileCreated(bool success) {
+ if (!success) {
+ ReturnFailure(kTemporaryFileError);
+ return;
+ }
+
+ Browser* browser = NULL;
+ TabContentsWrapper* tab_contents_wrapper = NULL;
+
+ if (!ExtensionTabUtil::GetTabById(tab_id_, profile(), include_incognito(),
+ &browser, NULL, &tab_contents_wrapper, NULL)) {
+ ReturnFailure(kTabClosedError);
+ return;
+ }
+
+ TabContents* tab_contents = tab_contents_wrapper->tab_contents();
+ registrar_.Add(this, content::NOTIFICATION_MHTML_GENERATED,
+ Source<RenderViewHost>(tab_contents->render_view_host()));
+ // TODO(jcivelli): we should listen for navigation in the tab, tab closed,
+ // renderer died.
+ g_browser_process->mhtml_generation_manager()->GenerateMHTML(
+ tab_contents, mhtml_path_);
+}
+
+void SavePageAsMHTMLFunction::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == content::NOTIFICATION_MHTML_GENERATED);
+
+ const MHTMLGenerationManager::NotificationDetails* save_details =
+ Details<MHTMLGenerationManager::NotificationDetails>(details).ptr();
+
+ if (mhtml_path_ != save_details->file_path) {
+ // This could happen if there are concurrent MHTML generations going on for
+ // the same tab.
+ LOG(WARNING) << "Received a notification that MHTML was generated but for a"
+ " different file.";
+ return;
+ }
+
+ registrar_.RemoveAll();
+
+ if (save_details->file_size <= 0) {
+ ReturnFailure(kMHTMLGenerationFailedError);
+ return;
+ }
+
+ if (save_details->file_size > std::numeric_limits<int>::max()) {
+ ReturnFailure(kFileTooBigError);
+ return;
+ }
+
+ ReturnSuccess(save_details->file_size);
+}
+
+void SavePageAsMHTMLFunction::ReturnFailure(const std::string& error) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ error_ = error;
+
+ SendResponse(false);
+
+ Release(); // Balanced in Run()
+}
+
+void SavePageAsMHTMLFunction::ReturnSuccess(int64 file_size) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ int child_id = render_view_host()->process()->id();
+ ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
+ child_id, mhtml_path_);
+
+ DictionaryValue* dict = new DictionaryValue();
+ result_.reset(dict);
+ dict->SetString("mhtmlFilePath", mhtml_path_.value());
+ dict->SetInteger("mhtmlFileLength", file_size);
+
+ SendResponse(true);
+
+ Release(); // Balanced in Run()
+}
diff --git a/chrome/browser/extensions/extension_save_page_api.h b/chrome/browser/extensions/extension_save_page_api.h
new file mode 100644
index 0000000..9de3f1b
--- /dev/null
+++ b/chrome/browser/extensions/extension_save_page_api.h
@@ -0,0 +1,45 @@
+// 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_EXTENSIONS_EXTENSION_SAVE_PAGE_API_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SAVE_PAGE_API_H_
+
+#include <string>
+
+#include "chrome/browser/extensions/extension_function.h"
+#include "content/browser/tab_contents/tab_contents_observer.h"
+#include "content/common/notification_observer.h"
+#include "content/common/notification_registrar.h"
+
+class SavePageAsMHTMLFunction : public AsyncExtensionFunction,
+ public NotificationObserver {
+ public:
+ SavePageAsMHTMLFunction();
+
+ private:
+ virtual ~SavePageAsMHTMLFunction();
+
+ virtual bool RunImpl() OVERRIDE;
+ virtual void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) OVERRIDE;
+
+ // Called on the file thread.
+ void CreateTemporaryFile();
+
+ // Called on the UI thread.
+ void TemporaryFileCreated(bool success);
+ void ReturnFailure(const std::string& error);
+ void ReturnSuccess(int64 file_size);
+
+ int tab_id_;
+
+ // The path to the temporary file containing the MHTML data.
+ FilePath mhtml_path_;
+
+ NotificationRegistrar registrar_;
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.savePage.saveAsMHTML")
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SAVE_PAGE_API_H_
diff --git a/chrome/browser/extensions/extension_save_page_apitest.cc b/chrome/browser/extensions/extension_save_page_apitest.cc
new file mode 100644
index 0000000..489ccf6
--- /dev/null
+++ b/chrome/browser/extensions/extension_save_page_apitest.cc
@@ -0,0 +1,30 @@
+// 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/base_switches.h"
+#include "base/command_line.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/common/chrome_switches.h"
+#include "net/base/mock_host_resolver.h"
+
+class ExtensionSavePageApiTest : public ExtensionApiTest {
+ public:
+ // TODO(jcivelli): remove this once save-page APIs are no longer experimental.
+ virtual void SetUpCommandLine(CommandLine* command_line) {
+ ExtensionApiTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
+ }
+
+ virtual void SetUpInProcessBrowserTestFixture() {
+ ExtensionApiTest::SetUpInProcessBrowserTestFixture();
+
+ host_resolver()->AddRule("www.a.com", "127.0.0.1");
+
+ ASSERT_TRUE(StartTestServer());
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(ExtensionSavePageApiTest, SavePageAsMHTML) {
+ ASSERT_TRUE(RunExtensionTest("save_page")) << message_;
+}