This source file includes following definitions.
- SetTestDelegate
- RunImpl
- OnMessageReceived
- CreateTemporaryFile
- TemporaryFileCreated
- MHTMLGenerated
- ReturnFailure
- ReturnSuccess
- GetWebContents
#include "chrome/browser/extensions/api/page_capture/page_capture_api.h"
#include <limits>
#include "base/bind.h"
#include "base/file_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/common/extension_messages.h"
using content::BrowserThread;
using content::ChildProcessSecurityPolicy;
using content::WebContents;
using extensions::PageCaptureSaveAsMHTMLFunction;
using webkit_blob::ShareableFileReference;
namespace SaveAsMHTML = extensions::api::page_capture::SaveAsMHTML;
namespace {
const char kFileTooBigError[] = "The MHTML file generated is too big.";
const char kMHTMLGenerationFailedError[] = "Failed to generate MHTML.";
const char kTemporaryFileError[] = "Failed to create a temporary file.";
const char kTabClosedError[] = "Cannot find the tab for thie request.";
}
static PageCaptureSaveAsMHTMLFunction::TestDelegate* test_delegate_ = NULL;
PageCaptureSaveAsMHTMLFunction::PageCaptureSaveAsMHTMLFunction() {
}
PageCaptureSaveAsMHTMLFunction::~PageCaptureSaveAsMHTMLFunction() {
if (mhtml_file_.get()) {
webkit_blob::ShareableFileReference* to_release = mhtml_file_.get();
to_release->AddRef();
mhtml_file_ = NULL;
BrowserThread::ReleaseSoon(BrowserThread::IO, FROM_HERE, to_release);
}
}
void PageCaptureSaveAsMHTMLFunction::SetTestDelegate(TestDelegate* delegate) {
test_delegate_ = delegate;
}
bool PageCaptureSaveAsMHTMLFunction::RunImpl() {
params_ = SaveAsMHTML::Params::Create(*args_);
EXTENSION_FUNCTION_VALIDATE(params_.get());
AddRef();
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&PageCaptureSaveAsMHTMLFunction::CreateTemporaryFile, this));
return true;
}
bool PageCaptureSaveAsMHTMLFunction::OnMessageReceived(
const IPC::Message& message) {
if (message.type() != ExtensionHostMsg_ResponseAck::ID)
return false;
int message_request_id;
PickleIterator iter(message);
if (!message.ReadInt(&iter, &message_request_id)) {
NOTREACHED() << "malformed extension message";
return true;
}
if (message_request_id != request_id())
return false;
Release();
return true;
}
void PageCaptureSaveAsMHTMLFunction::CreateTemporaryFile() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
bool success = base::CreateTemporaryFile(&mhtml_path_);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&PageCaptureSaveAsMHTMLFunction::TemporaryFileCreated, this,
success));
}
void PageCaptureSaveAsMHTMLFunction::TemporaryFileCreated(bool success) {
if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
if (success) {
mhtml_file_ = ShareableFileReference::GetOrCreate(
mhtml_path_,
ShareableFileReference::DELETE_ON_FINAL_RELEASE,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
.get());
}
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&PageCaptureSaveAsMHTMLFunction::TemporaryFileCreated, this,
success));
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!success) {
ReturnFailure(kTemporaryFileError);
return;
}
if (test_delegate_)
test_delegate_->OnTemporaryFileCreated(mhtml_path_);
WebContents* web_contents = GetWebContents();
if (!web_contents) {
ReturnFailure(kTabClosedError);
return;
}
web_contents->GenerateMHTML(
mhtml_path_,
base::Bind(&PageCaptureSaveAsMHTMLFunction::MHTMLGenerated, this));
}
void PageCaptureSaveAsMHTMLFunction::MHTMLGenerated(
int64 mhtml_file_size) {
if (mhtml_file_size <= 0) {
ReturnFailure(kMHTMLGenerationFailedError);
return;
}
if (mhtml_file_size > std::numeric_limits<int>::max()) {
ReturnFailure(kFileTooBigError);
return;
}
ReturnSuccess(mhtml_file_size);
}
void PageCaptureSaveAsMHTMLFunction::ReturnFailure(const std::string& error) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
error_ = error;
SendResponse(false);
Release();
}
void PageCaptureSaveAsMHTMLFunction::ReturnSuccess(int64 file_size) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
WebContents* web_contents = GetWebContents();
if (!web_contents || !render_view_host()) {
ReturnFailure(kTabClosedError);
return;
}
int child_id = render_view_host()->GetProcess()->GetID();
ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
child_id, mhtml_path_);
base::DictionaryValue* dict = new base::DictionaryValue();
SetResult(dict);
dict->SetString("mhtmlFilePath", mhtml_path_.value());
dict->SetInteger("mhtmlFileLength", file_size);
SendResponse(true);
}
WebContents* PageCaptureSaveAsMHTMLFunction::GetWebContents() {
Browser* browser = NULL;
content::WebContents* web_contents = NULL;
if (!ExtensionTabUtil::GetTabById(params_->details.tab_id,
GetProfile(),
include_incognito(),
&browser,
NULL,
&web_contents,
NULL)) {
return NULL;
}
return web_contents;
}