1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/android/offline_pages/offline_page_web_contents_observer.h"
14 #include "content/public/browser/web_contents.h"
15 #include "net/base/filename_util.h"
17 namespace offline_pages
{
19 const base::FilePath::CharType kMHTMLExtension
[] = FILE_PATH_LITERAL("mhtml");
20 const base::FilePath::CharType kDefaultFileName
[] =
21 FILE_PATH_LITERAL("offline_page");
22 const char kMHTMLFileNameExtension
[] = ".mhtml";
24 base::FilePath
GenerateFileName(GURL url
, base::string16 title
) {
25 return net::GenerateFileName(url
,
26 std::string(), // content disposition
27 std::string(), // charset
28 base::UTF16ToUTF8(title
), // suggested name
29 std::string(), // mime-type
31 .AddExtension(kMHTMLExtension
);
37 std::string
OfflinePageMHTMLArchiver::GetFileNameExtension() {
38 return kMHTMLFileNameExtension
;
41 OfflinePageMHTMLArchiver::OfflinePageMHTMLArchiver(
42 content::WebContents
* web_contents
,
43 const base::FilePath
& archive_dir
)
44 : archive_dir_(archive_dir
),
45 web_contents_(web_contents
),
46 weak_ptr_factory_(this) {
47 DCHECK(web_contents_
);
50 OfflinePageMHTMLArchiver::OfflinePageMHTMLArchiver(
51 const base::FilePath
& archive_dir
)
52 : archive_dir_(archive_dir
),
53 web_contents_(nullptr),
54 weak_ptr_factory_(this) {
57 OfflinePageMHTMLArchiver::~OfflinePageMHTMLArchiver() {
59 OfflinePageWebContentsObserver
* web_contents_observer
=
60 OfflinePageWebContentsObserver::FromWebContents(web_contents_
);
61 if (web_contents_observer
)
62 web_contents_observer
->set_main_frame_document_loaded_callback(
67 void OfflinePageMHTMLArchiver::CreateArchive(
68 const CreateArchiveCallback
& callback
) {
69 DCHECK(callback_
.is_null());
70 DCHECK(!callback
.is_null());
76 void OfflinePageMHTMLArchiver::GenerateMHTML() {
77 if (archive_dir_
.empty()) {
78 DVLOG(1) << "Archive path was empty. Can't create archive.";
79 ReportFailure(ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED
);
84 DVLOG(1) << "WebContents is missing. Can't create archive.";
85 ReportFailure(ArchiverResult::ERROR_CONTENT_UNAVAILABLE
);
89 OfflinePageWebContentsObserver
* web_contents_observer
=
90 OfflinePageWebContentsObserver::FromWebContents(web_contents_
);
91 if (!web_contents_observer
) {
92 DVLOG(1) << "WebContentsObserver is missing. Can't create archive.";
93 ReportFailure(ArchiverResult::ERROR_CONTENT_UNAVAILABLE
);
97 // If main frame document has not been loaded yet, wait until it is.
98 if (!web_contents_observer
->is_document_loaded_in_main_frame()) {
99 web_contents_observer
->set_main_frame_document_loaded_callback(
100 base::Bind(&OfflinePageMHTMLArchiver::DoGenerateMHTML
,
101 weak_ptr_factory_
.GetWeakPtr()));
108 void OfflinePageMHTMLArchiver::DoGenerateMHTML() {
109 // TODO(fgorski): Figure out if the actual URL can be different at
110 // the end of MHTML generation. Perhaps we should pull it out after the MHTML
112 GURL
url(web_contents_
->GetLastCommittedURL());
113 base::string16
title(web_contents_
->GetTitle());
114 base::FilePath
file_path(archive_dir_
.Append(GenerateFileName(url
, title
)));
116 web_contents_
->GenerateMHTML(
117 file_path
, base::Bind(&OfflinePageMHTMLArchiver::OnGenerateMHTMLDone
,
118 weak_ptr_factory_
.GetWeakPtr(), url
, file_path
));
121 void OfflinePageMHTMLArchiver::OnGenerateMHTMLDone(
123 const base::FilePath
& file_path
,
126 ReportFailure(ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED
);
128 callback_
.Run(this, ArchiverResult::SUCCESSFULLY_CREATED
, url
, file_path
,
133 void OfflinePageMHTMLArchiver::ReportFailure(ArchiverResult result
) {
134 DCHECK(result
!= ArchiverResult::SUCCESSFULLY_CREATED
);
135 callback_
.Run(this, result
, GURL(), base::FilePath(), 0);
138 } // namespace offline_pages