commit
0b24883649
48 changed files with 5988 additions and 34 deletions
35
atom.gyp
35
atom.gyp
|
@ -167,7 +167,6 @@
|
|||
'atom/browser/window_list.cc',
|
||||
'atom/browser/window_list.h',
|
||||
'atom/browser/window_list_observer.h',
|
||||
'atom/common/api/api_messages.cc',
|
||||
'atom/common/api/api_messages.h',
|
||||
'atom/common/api/atom_api_clipboard.cc',
|
||||
'atom/common/api/atom_api_crash_reporter.cc',
|
||||
|
@ -181,6 +180,8 @@
|
|||
'atom/common/api/atom_bindings.h',
|
||||
'atom/common/api/object_life_monitor.cc',
|
||||
'atom/common/api/object_life_monitor.h',
|
||||
'atom/common/common_message_generator.cc',
|
||||
'atom/common/common_message_generator.h',
|
||||
'atom/common/crash_reporter/crash_reporter.cc',
|
||||
'atom/common/crash_reporter/crash_reporter.h',
|
||||
'atom/common/crash_reporter/crash_reporter_linux.cc',
|
||||
|
@ -233,6 +234,9 @@
|
|||
'atom/renderer/atom_render_view_observer.h',
|
||||
'atom/renderer/atom_renderer_client.cc',
|
||||
'atom/renderer/atom_renderer_client.h',
|
||||
'chromium_src/chrome/browser/browser_process.cc',
|
||||
'chromium_src/chrome/browser/browser_process.h',
|
||||
'chromium_src/chrome/browser/chrome_notification_types.h',
|
||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener.cc',
|
||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener.h',
|
||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_mac.mm',
|
||||
|
@ -241,6 +245,24 @@
|
|||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h',
|
||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc',
|
||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h',
|
||||
'chromium_src/chrome/browser/printing/print_job.cc',
|
||||
'chromium_src/chrome/browser/printing/print_job.h',
|
||||
'chromium_src/chrome/browser/printing/print_job_manager.cc',
|
||||
'chromium_src/chrome/browser/printing/print_job_manager.h',
|
||||
'chromium_src/chrome/browser/printing/print_job_worker.cc',
|
||||
'chromium_src/chrome/browser/printing/print_job_worker.h',
|
||||
'chromium_src/chrome/browser/printing/print_job_worker_owner.h',
|
||||
'chromium_src/chrome/browser/printing/print_view_manager_base.cc',
|
||||
'chromium_src/chrome/browser/printing/print_view_manager_base.h',
|
||||
'chromium_src/chrome/browser/printing/print_view_manager_basic.cc',
|
||||
'chromium_src/chrome/browser/printing/print_view_manager_basic.h',
|
||||
'chromium_src/chrome/browser/printing/print_view_manager_observer.h',
|
||||
'chromium_src/chrome/browser/printing/printer_query.cc',
|
||||
'chromium_src/chrome/browser/printing/printer_query.h',
|
||||
'chromium_src/chrome/browser/printing/printing_message_filter.cc',
|
||||
'chromium_src/chrome/browser/printing/printing_message_filter.h',
|
||||
'chromium_src/chrome/browser/printing/printing_ui_web_contents_observer.cc',
|
||||
'chromium_src/chrome/browser/printing/printing_ui_web_contents_observer.h',
|
||||
'chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.cc',
|
||||
'chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h',
|
||||
'chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.cc',
|
||||
|
@ -249,6 +271,13 @@
|
|||
'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h',
|
||||
'chromium_src/chrome/browser/ui/views/status_icons/status_tray_state_changer_win.cc',
|
||||
'chromium_src/chrome/browser/ui/views/status_icons/status_tray_state_changer_win.h',
|
||||
'chromium_src/chrome/common/print_messages.cc',
|
||||
'chromium_src/chrome/common/print_messages.h',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper.cc',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper_win.cc',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper.h',
|
||||
'<@(native_mate_files)',
|
||||
],
|
||||
'framework_sources': [
|
||||
|
@ -439,6 +468,10 @@
|
|||
'vendor/brightray/brightray.gyp:brightray',
|
||||
'vendor/node/node.gyp:node_lib',
|
||||
],
|
||||
'defines': [
|
||||
# This is defined in skia/skia_common.gypi.
|
||||
'SK_SUPPORT_LEGACY_GETTOPDEVICE',
|
||||
],
|
||||
'sources': [
|
||||
'<@(lib_sources)',
|
||||
],
|
||||
|
|
|
@ -16,8 +16,30 @@
|
|||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct PrintSettings {
|
||||
bool silent;
|
||||
bool print_backgournd;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<PrintSettings> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
PrintSettings* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
dict.Get("silent", &(out->silent));
|
||||
dict.Get("printBackground", &(out->print_backgournd));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<gfx::Rect> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
|
@ -303,6 +325,22 @@ bool Window::IsWebViewFocused() {
|
|||
return window_->IsWebViewFocused();
|
||||
}
|
||||
|
||||
void Window::SetRepresentedFilename(const std::string& filename) {
|
||||
window_->SetRepresentedFilename(filename);
|
||||
}
|
||||
|
||||
std::string Window::GetRepresentedFilename() {
|
||||
return window_->GetRepresentedFilename();
|
||||
}
|
||||
|
||||
void Window::SetDocumentEdited(bool edited) {
|
||||
window_->SetDocumentEdited(edited);
|
||||
}
|
||||
|
||||
bool Window::IsDocumentEdited() {
|
||||
return window_->IsDocumentEdited();
|
||||
}
|
||||
|
||||
void Window::CapturePage(mate::Arguments* args) {
|
||||
gfx::Rect rect;
|
||||
base::Callback<void(v8::Handle<v8::Value>)> callback;
|
||||
|
@ -318,20 +356,14 @@ void Window::CapturePage(mate::Arguments* args) {
|
|||
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
|
||||
}
|
||||
|
||||
void Window::SetRepresentedFilename(const std::string& filename) {
|
||||
window_->SetRepresentedFilename(filename);
|
||||
}
|
||||
void Window::Print(mate::Arguments* args) {
|
||||
PrintSettings settings = { false, false };;
|
||||
if (args->Length() == 1 && !args->GetNext(&settings)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string Window::GetRepresentedFilename() {
|
||||
return window_->GetRepresentedFilename();
|
||||
}
|
||||
|
||||
void Window::SetDocumentEdited(bool edited) {
|
||||
window_->SetDocumentEdited(edited);
|
||||
}
|
||||
|
||||
bool Window::IsDocumentEdited() {
|
||||
return window_->IsDocumentEdited();
|
||||
window_->Print(settings.silent, settings.print_backgournd);
|
||||
}
|
||||
|
||||
mate::Handle<WebContents> Window::GetWebContents(v8::Isolate* isolate) const {
|
||||
|
@ -386,7 +418,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
.SetMethod("IsDocumentEdited", &Window::IsDocumentEdited)
|
||||
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
|
||||
.SetMethod("_openDevTools", &Window::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &Window::CloseDevTools)
|
||||
.SetMethod("isDevToolsOpened", &Window::IsDevToolsOpened)
|
||||
|
@ -395,6 +427,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("blurWebView", &Window::BlurWebView)
|
||||
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
|
||||
.SetMethod("capturePage", &Window::CapturePage)
|
||||
.SetMethod("print", &Window::Print)
|
||||
.SetMethod("_getWebContents", &Window::GetWebContents)
|
||||
.SetMethod("_getDevToolsWebContents", &Window::GetDevToolsWebContents);
|
||||
}
|
||||
|
|
|
@ -97,11 +97,12 @@ class Window : public mate::EventEmitter,
|
|||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
void CapturePage(mate::Arguments* args);
|
||||
void SetRepresentedFilename(const std::string& filename);
|
||||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void CapturePage(mate::Arguments* args);
|
||||
void Print(mate::Arguments* args);
|
||||
|
||||
// APIs for WebContents.
|
||||
mate::Handle<WebContents> GetWebContents(v8::Isolate* isolate) const;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "chrome/browser/printing/printing_message_filter.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/resource_dispatcher_host.h"
|
||||
|
@ -48,6 +49,11 @@ AtomBrowserClient::AtomBrowserClient()
|
|||
AtomBrowserClient::~AtomBrowserClient() {
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host) {
|
||||
host->AddFilter(new PrintingMessageFilter(host->GetID()));
|
||||
}
|
||||
|
||||
void AtomBrowserClient::ResourceDispatcherHostCreated() {
|
||||
resource_dispatcher_delegate_.reset(new AtomResourceDispatcherHostDelegate);
|
||||
content::ResourceDispatcherHost::Get()->SetDelegate(
|
||||
|
|
|
@ -20,6 +20,8 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
|||
|
||||
protected:
|
||||
// content::ContentBrowserClient:
|
||||
virtual void RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host) OVERRIDE;
|
||||
virtual void ResourceDispatcherHostCreated() OVERRIDE;
|
||||
virtual content::AccessTokenStore* CreateAccessTokenStore() OVERRIDE;
|
||||
virtual void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
#include "base/threading/worker_pool.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "net/url_request/data_protocol_handler.h"
|
||||
|
@ -19,7 +20,8 @@ using content::BrowserThread;
|
|||
namespace atom {
|
||||
|
||||
AtomBrowserContext::AtomBrowserContext()
|
||||
: job_factory_(new AtomURLRequestJobFactory) {
|
||||
: fake_browser_process_(new BrowserProcess),
|
||||
job_factory_(new AtomURLRequestJobFactory) {
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "brightray/browser/browser_context.h"
|
||||
|
||||
class BrowserProcess;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomURLRequestJobFactory;
|
||||
|
@ -28,6 +30,9 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
|||
content::ProtocolHandlerScopedVector* interceptors) OVERRIDE;
|
||||
|
||||
private:
|
||||
// A fake BrowserProcess object that used to feed the source code from chrome.
|
||||
scoped_ptr<BrowserProcess> fake_browser_process_;
|
||||
|
||||
AtomURLRequestJobFactory* job_factory_; // Weak reference.
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/invalidate_type.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
|
@ -66,6 +67,8 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
|
|||
weak_factory_(this),
|
||||
inspectable_web_contents_(
|
||||
brightray::InspectableWebContents::Create(web_contents)) {
|
||||
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
|
||||
|
||||
options.Get(switches::kFrame, &has_frame_);
|
||||
options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_);
|
||||
|
||||
|
@ -192,11 +195,16 @@ std::string NativeWindow::GetRepresentedFilename() {
|
|||
void NativeWindow::SetDocumentEdited(bool edited) {
|
||||
}
|
||||
|
||||
bool NativeWindow::IsDocumentEdited() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void NativeWindow::SetMenu(ui::MenuModel* menu) {
|
||||
}
|
||||
|
||||
bool NativeWindow::IsDocumentEdited() {
|
||||
return false;
|
||||
void NativeWindow::Print(bool silent, bool print_background) {
|
||||
printing::PrintViewManagerBasic::FromWebContents(GetWebContents())->
|
||||
PrintNow(silent, print_background);
|
||||
}
|
||||
|
||||
bool NativeWindow::HasModalDialog() {
|
||||
|
|
|
@ -136,8 +136,8 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
|||
virtual void SetRepresentedFilename(const std::string& filename);
|
||||
virtual std::string GetRepresentedFilename();
|
||||
virtual void SetDocumentEdited(bool edited);
|
||||
virtual void SetMenu(ui::MenuModel* menu);
|
||||
virtual bool IsDocumentEdited();
|
||||
virtual void SetMenu(ui::MenuModel* menu);
|
||||
virtual bool HasModalDialog();
|
||||
virtual gfx::NativeWindow GetNativeWindow() = 0;
|
||||
|
||||
|
@ -156,6 +156,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
|||
virtual void CapturePage(const gfx::Rect& rect,
|
||||
const CapturePageCallback& callback);
|
||||
|
||||
// Print current page.
|
||||
virtual void Print(bool silent, bool print_background);
|
||||
|
||||
// The same with closing a tab in a real browser.
|
||||
//
|
||||
// Should be called by platform code when user want to close the window.
|
||||
|
|
|
@ -1,33 +1,34 @@
|
|||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Get basic type definitions.
|
||||
#define IPC_MESSAGE_IMPL
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/common_message_generator.h"
|
||||
|
||||
// Generate constructors.
|
||||
#include "ipc/struct_constructor_macros.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/common_message_generator.h"
|
||||
|
||||
// Generate destructors.
|
||||
#include "ipc/struct_destructor_macros.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/common_message_generator.h"
|
||||
|
||||
// Generate param traits write methods.
|
||||
#include "ipc/param_traits_write_macros.h"
|
||||
namespace IPC {
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/common_message_generator.h"
|
||||
} // namespace IPC
|
||||
|
||||
// Generate param traits read methods.
|
||||
#include "ipc/param_traits_read_macros.h"
|
||||
namespace IPC {
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/common_message_generator.h"
|
||||
} // namespace IPC
|
||||
|
||||
// Generate param traits log methods.
|
||||
#include "ipc/param_traits_log_macros.h"
|
||||
namespace IPC {
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/common_message_generator.h"
|
||||
} // namespace IPC
|
||||
|
8
atom/common/common_message_generator.h
Normal file
8
atom/common/common_message_generator.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Multiply-included file, no traditional include guard.
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "chrome/common/print_messages.h"
|
|
@ -11,6 +11,7 @@
|
|||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/api/atom_renderer_bindings.h"
|
||||
#include "atom/renderer/atom_render_view_observer.h"
|
||||
#include "chrome/renderer/printing/print_web_view_helper.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "content/public/renderer/render_frame_observer.h"
|
||||
#include "base/command_line.h"
|
||||
|
@ -105,6 +106,7 @@ void AtomRendererClient::RenderFrameCreated(
|
|||
}
|
||||
|
||||
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
|
||||
new printing::PrintWebViewHelper(render_view);
|
||||
new AtomRenderViewObserver(render_view, this);
|
||||
}
|
||||
|
||||
|
|
28
chromium_src/chrome/browser/browser_process.cc
Normal file
28
chromium_src/chrome/browser/browser_process.cc
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2012 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/browser_process.h"
|
||||
|
||||
#include "chrome/browser/printing/print_job_manager.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
BrowserProcess* g_browser_process = NULL;
|
||||
|
||||
BrowserProcess::BrowserProcess() {
|
||||
g_browser_process = this;
|
||||
|
||||
print_job_manager_.reset(new printing::PrintJobManager);
|
||||
}
|
||||
|
||||
BrowserProcess::~BrowserProcess() {
|
||||
g_browser_process = NULL;
|
||||
}
|
||||
|
||||
std::string BrowserProcess::GetApplicationLocale() {
|
||||
return l10n_util::GetApplicationLocale("");
|
||||
}
|
||||
|
||||
printing::PrintJobManager* BrowserProcess::print_job_manager() {
|
||||
return print_job_manager_.get();
|
||||
}
|
41
chromium_src/chrome/browser/browser_process.h
Normal file
41
chromium_src/chrome/browser/browser_process.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
// This interface is for managing the global services of the application. Each
|
||||
// service is lazily created when requested the first time. The service getters
|
||||
// will return NULL if the service is not available, so callers must check for
|
||||
// this condition.
|
||||
|
||||
#ifndef CHROME_BROWSER_BROWSER_PROCESS_H_
|
||||
#define CHROME_BROWSER_BROWSER_PROCESS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace printing {
|
||||
class PrintJobManager;
|
||||
}
|
||||
|
||||
// NOT THREAD SAFE, call only from the main thread.
|
||||
// These functions shouldn't return NULL unless otherwise noted.
|
||||
class BrowserProcess {
|
||||
public:
|
||||
BrowserProcess();
|
||||
~BrowserProcess();
|
||||
|
||||
std::string GetApplicationLocale();
|
||||
|
||||
printing::PrintJobManager* print_job_manager();
|
||||
|
||||
private:
|
||||
scoped_ptr<printing::PrintJobManager> print_job_manager_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserProcess);
|
||||
};
|
||||
|
||||
extern BrowserProcess* g_browser_process;
|
||||
|
||||
#endif // CHROME_BROWSER_BROWSER_PROCESS_H_
|
949
chromium_src/chrome/browser/chrome_notification_types.h
Normal file
949
chromium_src/chrome/browser/chrome_notification_types.h
Normal file
|
@ -0,0 +1,949 @@
|
|||
// Copyright 2012 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_CHROME_NOTIFICATION_TYPES_H_
|
||||
#define CHROME_BROWSER_CHROME_NOTIFICATION_TYPES_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "content/public/browser/notification_types.h"
|
||||
|
||||
namespace chrome {
|
||||
|
||||
enum NotificationType {
|
||||
NOTIFICATION_CHROME_START = content::NOTIFICATION_CONTENT_END,
|
||||
|
||||
// Browser-window ----------------------------------------------------------
|
||||
|
||||
// This message is sent after a window has been opened. The source is a
|
||||
// Source<Browser> containing the affected Browser. No details are
|
||||
// expected.
|
||||
NOTIFICATION_BROWSER_OPENED = NOTIFICATION_CHROME_START,
|
||||
|
||||
// This message is sent soon after BROWSER_OPENED, and indicates that
|
||||
// the Browser's |window_| is now non-NULL. The source is a Source<Browser>
|
||||
// containing the affected Browser. No details are expected.
|
||||
NOTIFICATION_BROWSER_WINDOW_READY,
|
||||
|
||||
// This message is sent when a browser is closing. The source is a
|
||||
// Source<Browser> containing the affected Browser. No details are expected.
|
||||
// This is sent prior to BROWSER_CLOSED, and may be sent more than once for a
|
||||
// particular browser.
|
||||
NOTIFICATION_BROWSER_CLOSING,
|
||||
|
||||
// This message is sent after a window has been closed. The source is a
|
||||
// Source<Browser> containing the affected Browser. No details are exptected.
|
||||
NOTIFICATION_BROWSER_CLOSED,
|
||||
|
||||
// This message is sent when closing a browser has been cancelled, either by
|
||||
// the user cancelling a beforeunload dialog, or IsClosingPermitted()
|
||||
// disallowing closing. This notification implies that no BROWSER_CLOSING or
|
||||
// BROWSER_CLOSED notification will be sent.
|
||||
// The source is a Source<Browser> containing the affected browser. No details
|
||||
// are expected.
|
||||
NOTIFICATION_BROWSER_CLOSE_CANCELLED,
|
||||
|
||||
// Indicates that a top window has been closed. The source is the HWND
|
||||
// that was closed, no details are expected.
|
||||
NOTIFICATION_WINDOW_CLOSED,
|
||||
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
|
||||
// On Linux maximize can be an asynchronous operation. This notification
|
||||
// indicates that the window has been maximized. The source is
|
||||
// a Source<BrowserWindow> containing the BrowserWindow that was maximized.
|
||||
// No details are expected.
|
||||
NOTIFICATION_BROWSER_WINDOW_MAXIMIZED,
|
||||
#endif
|
||||
|
||||
// Sent when the language (English, French...) for a page has been detected.
|
||||
// The details Details<std::string> contain the ISO 639-1 language code and
|
||||
// the source is Source<WebContents>.
|
||||
NOTIFICATION_TAB_LANGUAGE_DETERMINED,
|
||||
|
||||
// Sent when a page has been translated. The source is the tab for that page
|
||||
// (Source<WebContents>) and the details are the language the page was
|
||||
// originally in and the language it was translated to
|
||||
// (std::pair<std::string, std::string>).
|
||||
NOTIFICATION_PAGE_TRANSLATED,
|
||||
|
||||
// The user has changed the browser theme. The source is a
|
||||
// Source<ThemeService>. There are no details.
|
||||
NOTIFICATION_BROWSER_THEME_CHANGED,
|
||||
|
||||
#if defined(USE_AURA)
|
||||
// The user has changed the fling curve configuration.
|
||||
// Source<GesturePrefsObserver>. There are no details.
|
||||
NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED,
|
||||
#endif // defined(USE_AURA)
|
||||
|
||||
// Sent when the renderer returns focus to the browser, as part of focus
|
||||
// traversal. The source is the browser, there are no details.
|
||||
NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
|
||||
|
||||
// A new tab is created from an existing tab to serve as a target of a
|
||||
// navigation that is about to happen. The source will be a Source<Profile>
|
||||
// corresponding to the profile in which the new tab will live. Details in
|
||||
// the form of a RetargetingDetails object are provided.
|
||||
NOTIFICATION_RETARGETING,
|
||||
|
||||
// Application-wide ----------------------------------------------------------
|
||||
|
||||
// This message is sent when the application is terminating (the last
|
||||
// browser window has shutdown as part of an explicit user-initiated exit,
|
||||
// or the user closed the last browser window on Windows/Linux and there are
|
||||
// no BackgroundContents keeping the browser running). No source or details
|
||||
// are passed.
|
||||
NOTIFICATION_APP_TERMINATING,
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// This notification is sent when the app has no key window, such as when
|
||||
// all windows are closed but the app is still active. No source or details
|
||||
// are provided.
|
||||
NOTIFICATION_NO_KEY_WINDOW,
|
||||
#endif
|
||||
|
||||
// This is sent when the user has chosen to exit the app, but before any
|
||||
// browsers have closed. This is sent if the user chooses to exit (via exit
|
||||
// menu item or keyboard shortcut) or to restart the process (such as in flags
|
||||
// page), not if Chrome exits by some other means (such as the user closing
|
||||
// the last window). No source or details are passed.
|
||||
//
|
||||
// Note that receiving this notification does not necessarily mean the process
|
||||
// will exit because the shutdown process can be cancelled by an unload
|
||||
// handler. Use APP_TERMINATING for such needs.
|
||||
NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
|
||||
|
||||
// Application-modal dialogs -----------------------------------------------
|
||||
|
||||
// Sent after an application-modal dialog has been shown. The source
|
||||
// is the dialog.
|
||||
NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
|
||||
|
||||
// This message is sent when a new InfoBar has been added to an
|
||||
// InfoBarService. The source is a Source<InfoBarService> with a pointer to
|
||||
// the InfoBarService the InfoBar was added to. The details is a
|
||||
// Details<InfoBar::AddedDetails>.
|
||||
NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
|
||||
|
||||
// This message is sent when an InfoBar is about to be removed from an
|
||||
// InfoBarService. The source is a Source<InfoBarService> with a pointer to
|
||||
// the InfoBarService the InfoBar was removed from. The details is a
|
||||
// Details<InfoBar::RemovedDetails>.
|
||||
NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
|
||||
|
||||
// This message is sent when an InfoBar is replacing another infobar in an
|
||||
// InfoBarService. The source is a Source<InfoBarService> with a pointer to
|
||||
// the InfoBarService the InfoBar was removed from. The details is a
|
||||
// Details<InfoBar::ReplacedDetails>.
|
||||
NOTIFICATION_TAB_CONTENTS_INFOBAR_REPLACED,
|
||||
|
||||
// Used to fire notifications about how long various events took to
|
||||
// complete. E.g., this is used to get more fine grained timings from the
|
||||
// new tab page. The source is a WebContents and the details is a
|
||||
// MetricEventDurationDetails.
|
||||
NOTIFICATION_METRIC_EVENT_DURATION,
|
||||
|
||||
// This notification is sent when extensions::TabHelper::SetExtensionApp is
|
||||
// invoked. The source is the extensions::TabHelper SetExtensionApp was
|
||||
// invoked on.
|
||||
NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED,
|
||||
|
||||
// Tabs --------------------------------------------------------------------
|
||||
|
||||
// Sent when a tab is added to a WebContentsDelegate. The source is the
|
||||
// WebContentsDelegate and the details is the added WebContents.
|
||||
NOTIFICATION_TAB_ADDED,
|
||||
|
||||
// This notification is sent after a tab has been appended to the tab_strip.
|
||||
// The source is a Source<WebContents> of the tab being added. There
|
||||
// are no details.
|
||||
NOTIFICATION_TAB_PARENTED,
|
||||
|
||||
// This message is sent before a tab has been closed. The source is a
|
||||
// Source<NavigationController> with a pointer to the controller for the
|
||||
// closed tab. No details are expected.
|
||||
//
|
||||
// See also content::NOTIFICATION_WEB_CONTENTS_DESTROYED, which is sent when
|
||||
// the WebContents containing the NavigationController is destroyed.
|
||||
NOTIFICATION_TAB_CLOSING,
|
||||
|
||||
// Stuff inside the tabs ---------------------------------------------------
|
||||
|
||||
// This notification is sent when the result of a find-in-page search is
|
||||
// available with the browser process. The source is a Source<WebContents>.
|
||||
// Details encompass a FindNotificationDetail object that tells whether the
|
||||
// match was found or not found.
|
||||
NOTIFICATION_FIND_RESULT_AVAILABLE,
|
||||
|
||||
// BackgroundContents ------------------------------------------------------
|
||||
|
||||
// A new background contents was opened by script. The source is the parent
|
||||
// profile and the details are BackgroundContentsOpenedDetails.
|
||||
NOTIFICATION_BACKGROUND_CONTENTS_OPENED,
|
||||
|
||||
// The background contents navigated to a new location. The source is the
|
||||
// parent Profile, and the details are the BackgroundContents that was
|
||||
// navigated.
|
||||
NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED,
|
||||
|
||||
// The background contents were closed by someone invoking window.close()
|
||||
// or the parent application was uninstalled.
|
||||
// The source is the parent profile, and the details are the
|
||||
// BackgroundContents.
|
||||
NOTIFICATION_BACKGROUND_CONTENTS_CLOSED,
|
||||
|
||||
// The background contents is being deleted. The source is the
|
||||
// parent Profile, and the details are the BackgroundContents being deleted.
|
||||
NOTIFICATION_BACKGROUND_CONTENTS_DELETED,
|
||||
|
||||
// The background contents has crashed. The source is the parent Profile,
|
||||
// and the details are the BackgroundContents.
|
||||
NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED,
|
||||
|
||||
// The background contents associated with a hosted app has changed (either
|
||||
// a new background contents has been created, or an existing background
|
||||
// contents has closed). The source is the parent Profile, and the details
|
||||
// are the BackgroundContentsService.
|
||||
NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED,
|
||||
|
||||
// Chrome has entered/exited background mode. The source is the
|
||||
// BackgroundModeManager and the details are a boolean value which is set to
|
||||
// true if Chrome is now in background mode.
|
||||
NOTIFICATION_BACKGROUND_MODE_CHANGED,
|
||||
|
||||
// This is sent when a login prompt is shown. The source is the
|
||||
// Source<NavigationController> for the tab in which the prompt is shown.
|
||||
// Details are a LoginNotificationDetails which provide the LoginHandler
|
||||
// that should be given authentication.
|
||||
NOTIFICATION_AUTH_NEEDED,
|
||||
|
||||
// This is sent when authentication credentials have been supplied (either
|
||||
// by the user or by an automation service), but before we've actually
|
||||
// received another response from the server. The source is the
|
||||
// Source<NavigationController> for the tab in which the prompt was shown.
|
||||
// Details are an AuthSuppliedLoginNotificationDetails which provide the
|
||||
// LoginHandler that should be given authentication as well as the supplied
|
||||
// username and password.
|
||||
NOTIFICATION_AUTH_SUPPLIED,
|
||||
|
||||
// This is sent when an authentication request has been dismissed without
|
||||
// supplying credentials (either by the user or by an automation service).
|
||||
// The source is the Source<NavigationController> for the tab in which the
|
||||
// prompt was shown. Details are a LoginNotificationDetails which provide
|
||||
// the LoginHandler that should be cancelled.
|
||||
NOTIFICATION_AUTH_CANCELLED,
|
||||
|
||||
// History -----------------------------------------------------------------
|
||||
|
||||
// Sent when a history service has finished loading. The source is the
|
||||
// profile that the history service belongs to, and the details is the
|
||||
// HistoryService.
|
||||
NOTIFICATION_HISTORY_LOADED,
|
||||
|
||||
// Sent when a URL has been added or modified. This is used by the in-memory
|
||||
// URL database and the InMemoryURLIndex (both used by autocomplete) to track
|
||||
// changes to the main history system.
|
||||
//
|
||||
// The source is the profile owning the history service that changed, and
|
||||
// the details is history::URLsModifiedDetails that lists the modified or
|
||||
// added URLs.
|
||||
NOTIFICATION_HISTORY_URLS_MODIFIED,
|
||||
|
||||
// Sent when the user visits a URL.
|
||||
//
|
||||
// The source is the profile owning the history service that changed, and
|
||||
// the details is history::URLVisitedDetails.
|
||||
NOTIFICATION_HISTORY_URL_VISITED,
|
||||
|
||||
// Sent when one or more URLs are deleted.
|
||||
//
|
||||
// The source is the profile owning the history service that changed, and
|
||||
// the details is history::URLsDeletedDetails that lists the deleted URLs.
|
||||
NOTIFICATION_HISTORY_URLS_DELETED,
|
||||
|
||||
// Sent when a keyword search term is updated. The source is the Profile and
|
||||
// the details is history::KeywordSearchUpdatedDetails.
|
||||
NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_UPDATED,
|
||||
|
||||
// Sent when a keyword search term is deleted. The source is the Profile and
|
||||
// the details is history::KeywordSearchDeletedDetails.
|
||||
NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_DELETED,
|
||||
|
||||
// Sent by history when the favicon of a URL changes. The source is the
|
||||
// profile, and the details is FaviconChangedDetails (see
|
||||
// chrome/browser/favicon/favicon_changed_details.h).
|
||||
NOTIFICATION_FAVICON_CHANGED,
|
||||
|
||||
// Sent by FaviconTabHelper when a tab's favicon has been successfully
|
||||
// updated. The details are a bool indicating whether the
|
||||
// NavigationEntry's favicon URL has changed since the previous
|
||||
// NOTIFICATION_FAVICON_UPDATED notification. The details are true if
|
||||
// there was no previous NOTIFICATION_FAVICON_UPDATED notification for the
|
||||
// current NavigationEntry.
|
||||
NOTIFICATION_FAVICON_UPDATED,
|
||||
|
||||
// Profiles -----------------------------------------------------------------
|
||||
|
||||
// Sent after a Profile has been created. This notification is sent both for
|
||||
// normal and OTR profiles.
|
||||
// The details are none and the source is the new profile.
|
||||
NOTIFICATION_PROFILE_CREATED,
|
||||
|
||||
// Sent after a Profile has been added to ProfileManager.
|
||||
// The details are none and the source is the new profile.
|
||||
NOTIFICATION_PROFILE_ADDED,
|
||||
|
||||
// Sent before a Profile is destroyed. This notification is sent both for
|
||||
// normal and OTR profiles.
|
||||
// The details are none and the source is a Profile*.
|
||||
NOTIFICATION_PROFILE_DESTROYED,
|
||||
|
||||
// Sent after the URLRequestContextGetter for a Profile has been initialized.
|
||||
// The details are none and the source is a Profile*.
|
||||
NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
|
||||
|
||||
// TopSites ----------------------------------------------------------------
|
||||
|
||||
// Sent by TopSites when it finishes loading. The source is the profile the
|
||||
// details the TopSites.
|
||||
NOTIFICATION_TOP_SITES_LOADED,
|
||||
|
||||
// Sent by TopSites when the either one of the most visited urls changed, or
|
||||
// one of the images changes. The source is the TopSites, the details not
|
||||
// used.
|
||||
NOTIFICATION_TOP_SITES_CHANGED,
|
||||
|
||||
// Task Manager ------------------------------------------------------------
|
||||
|
||||
// Sent when a renderer process is notified of new v8 heap statistics. The
|
||||
// source is the ID of the renderer process, and the details are a
|
||||
// V8HeapStatsDetails object.
|
||||
NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
|
||||
|
||||
// Non-history storage services --------------------------------------------
|
||||
|
||||
// Sent when a TemplateURL is removed from the model. The source is the
|
||||
// Profile, and the details the id of the TemplateURL being removed.
|
||||
NOTIFICATION_TEMPLATE_URL_REMOVED,
|
||||
|
||||
// Sent when the prefs relating to the default search engine have changed due
|
||||
// to policy. Source and details are unused.
|
||||
NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
|
||||
|
||||
// The state of a web resource has been changed. A resource may have been
|
||||
// added, removed, or altered. Source is WebResourceService, and the
|
||||
// details are NoDetails.
|
||||
NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED,
|
||||
|
||||
// A safe browsing database update completed. Source is the
|
||||
// SafeBrowsingService and the details are a bool indicating whether the
|
||||
// update was successful.
|
||||
NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
|
||||
|
||||
// Autocomplete ------------------------------------------------------------
|
||||
|
||||
// Sent by the autocomplete controller when done. The source is the
|
||||
// AutocompleteController, the details not used.
|
||||
NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
|
||||
|
||||
// This is sent when an item of the Omnibox popup is selected. The source
|
||||
// is the profile.
|
||||
NOTIFICATION_OMNIBOX_OPENED_URL,
|
||||
|
||||
// This is sent from Instant when the omnibox focus state changes.
|
||||
NOTIFICATION_OMNIBOX_FOCUS_CHANGED,
|
||||
|
||||
// Sent when the Google URL for a profile has been updated. Some services
|
||||
// cache this value and need to update themselves when it changes. See
|
||||
// google_util::GetGoogleURLAndUpdateIfNecessary(). The source is the
|
||||
// Profile, the details a GoogleURLTracker::UpdatedDetails containing the old
|
||||
// and new URLs.
|
||||
//
|
||||
// Note that because incognito mode requests for the GoogleURLTracker are
|
||||
// redirected to the non-incognito profile's copy, this notification will only
|
||||
// ever fire on non-incognito profiles; thus listeners should use
|
||||
// GetOriginalProfile() when constructing a Source to filter against.
|
||||
NOTIFICATION_GOOGLE_URL_UPDATED,
|
||||
|
||||
// Printing ----------------------------------------------------------------
|
||||
|
||||
// Notification from PrintJob that an event occurred. It can be that a page
|
||||
// finished printing or that the print job failed. Details is
|
||||
// PrintJob::EventDetails. Source is a PrintJob.
|
||||
NOTIFICATION_PRINT_JOB_EVENT,
|
||||
|
||||
// Sent when a PrintJob has been released.
|
||||
// Source is the WebContents that holds the print job.
|
||||
NOTIFICATION_PRINT_JOB_RELEASED,
|
||||
|
||||
// Shutdown ----------------------------------------------------------------
|
||||
|
||||
// Sent when WM_ENDSESSION has been received, after the browsers have been
|
||||
// closed but before browser process has been shutdown. The source/details
|
||||
// are all source and no details.
|
||||
NOTIFICATION_SESSION_END,
|
||||
|
||||
// User Scripts ------------------------------------------------------------
|
||||
|
||||
// Sent when there are new user scripts available. The details are a
|
||||
// pointer to SharedMemory containing the new scripts.
|
||||
NOTIFICATION_USER_SCRIPTS_UPDATED,
|
||||
|
||||
// Extensions --------------------------------------------------------------
|
||||
|
||||
// Sent when a CrxInstaller finishes. Source is the CrxInstaller that
|
||||
// finished. The details are the extension which was installed.
|
||||
NOTIFICATION_CRX_INSTALLER_DONE,
|
||||
|
||||
// Sent when the known installed extensions have all been loaded. In
|
||||
// testing scenarios this can happen multiple times if extensions are
|
||||
// unloaded and reloaded. The source is a Profile.
|
||||
NOTIFICATION_EXTENSIONS_READY,
|
||||
|
||||
// Sent when an extension icon being displayed in the location bar is updated.
|
||||
// The source is the Profile and the details are the WebContents for
|
||||
// the tab.
|
||||
NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
|
||||
|
||||
// DEPRECATED: Use ExtensionRegistry::AddObserver instead.
|
||||
//
|
||||
// Sent when a new extension is loaded. The details are an Extension, and
|
||||
// the source is a Profile.
|
||||
NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
|
||||
|
||||
// An error occured while attempting to load an extension. The details are a
|
||||
// string with details about why the load failed.
|
||||
NOTIFICATION_EXTENSION_LOAD_ERROR,
|
||||
|
||||
// Sent when an extension is enabled. Under most circumstances, listeners
|
||||
// will want to use NOTIFICATION_EXTENSION_LOADED_DEPRECATED. This
|
||||
// notification is only
|
||||
// fired when the "Enable" button is hit in the extensions tab. The details
|
||||
// are an Extension, and the source is a Profile.
|
||||
NOTIFICATION_EXTENSION_ENABLED,
|
||||
|
||||
// Sent when attempting to load a new extension, but they are disabled. The
|
||||
// details are an Extension*, and the source is a Profile*.
|
||||
NOTIFICATION_EXTENSION_UPDATE_DISABLED,
|
||||
|
||||
// Sent when an extension's permissions change. The details are an
|
||||
// UpdatedExtensionPermissionsInfo, and the source is a Profile.
|
||||
NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
|
||||
|
||||
// Sent when new extensions are installed, or existing extensions are updated.
|
||||
// The details are an InstalledExtensionInfo, and the source is a Profile.
|
||||
NOTIFICATION_EXTENSION_INSTALLED,
|
||||
|
||||
// An error occured during extension install. The details are a string with
|
||||
// details about why the install failed.
|
||||
NOTIFICATION_EXTENSION_INSTALL_ERROR,
|
||||
|
||||
// Sent when an extension has been uninstalled. The details are an Extension,
|
||||
// and the source is a Profile.
|
||||
NOTIFICATION_EXTENSION_UNINSTALLED,
|
||||
|
||||
// Sent when an extension uninstall is not allowed because the extension is
|
||||
// not user manageable. The details are an Extension, and the source is a
|
||||
// Profile.
|
||||
NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED,
|
||||
|
||||
// DEPRECATED: Use ExtensionRegistry::AddObserver instead.
|
||||
//
|
||||
// Sent when an extension is unloaded. This happens when an extension is
|
||||
// uninstalled or disabled. The details are an UnloadedExtensionInfo, and
|
||||
// the source is a Profile.
|
||||
//
|
||||
// Note that when this notification is sent, ExtensionService has already
|
||||
// removed the extension from its internal state.
|
||||
NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
|
||||
|
||||
// Sent when an Extension object is removed from ExtensionService. This
|
||||
// can happen when an extension is uninstalled, upgraded, or blacklisted,
|
||||
// including all cases when the Extension is deleted. The details are an
|
||||
// Extension, and the source is a Profile.
|
||||
NOTIFICATION_EXTENSION_REMOVED,
|
||||
|
||||
// Sent after a new ExtensionHost is created. The details are
|
||||
// an ExtensionHost* and the source is a Profile*.
|
||||
NOTIFICATION_EXTENSION_HOST_CREATED,
|
||||
|
||||
// Sent before an ExtensionHost is destroyed. The details are
|
||||
// an ExtensionHost* and the source is a Profile*.
|
||||
NOTIFICATION_EXTENSION_HOST_DESTROYED,
|
||||
|
||||
// Sent by an ExtensionHost when it has finished its initial page load,
|
||||
// including any external resources.
|
||||
// The details are an ExtensionHost* and the source is a Profile*.
|
||||
NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
|
||||
|
||||
// Sent by an ExtensionHost when its render view requests closing through
|
||||
// window.close(). The details are an ExtensionHost* and the source is a
|
||||
// Profile*.
|
||||
NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
|
||||
|
||||
// Sent when extension render process ends (whether it crashes or closes).
|
||||
// The details are an ExtensionHost* and the source is a Profile*. Not sent
|
||||
// during browser shutdown.
|
||||
NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
|
||||
|
||||
// Sent when a background page is ready so other components can load.
|
||||
NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
|
||||
|
||||
// Sent when a browser action's state has changed. The source is the
|
||||
// ExtensionAction* that changed. The details are the Profile* that the
|
||||
// browser action belongs to.
|
||||
NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
|
||||
|
||||
// Sent when the count of page actions has changed. Note that some of them
|
||||
// may not apply to the current page. The source is a LocationBar*. There
|
||||
// are no details.
|
||||
NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED,
|
||||
|
||||
// Sent when a browser action's visibility has changed. The source is the
|
||||
// ExtensionPrefs* that changed, and the details are a std::string with the
|
||||
// extension's ID.
|
||||
NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
|
||||
|
||||
// Sent when a page action's visibility has changed. The source is the
|
||||
// ExtensionAction* that changed. The details are a WebContents*.
|
||||
NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
|
||||
|
||||
// Sent when a system indicator action's state has changed. The source is the
|
||||
// Profile* that the browser action belongs to. The details are the
|
||||
// ExtensionAction* that changed.
|
||||
NOTIFICATION_EXTENSION_SYSTEM_INDICATOR_UPDATED,
|
||||
|
||||
// Sent when an extension command has been removed. The source is the profile
|
||||
// and the details is a std::pair of two std::string objects (an extension ID
|
||||
// and the name of the command being removed).
|
||||
NOTIFICATION_EXTENSION_COMMAND_REMOVED,
|
||||
|
||||
// Sent when an extension command has been added. The source is the profile
|
||||
// and the details is a std::pair of two std::string objects (an extension ID
|
||||
// and the name of the command being added).
|
||||
NOTIFICATION_EXTENSION_COMMAND_ADDED,
|
||||
|
||||
// Sent when an extension command shortcut for a browser action is activated
|
||||
// on Mac. The source is the profile and the details is a std::pair of a
|
||||
// std::string containing an extension ID and a gfx::NativeWindow for the
|
||||
// associated window.
|
||||
NOTIFICATION_EXTENSION_COMMAND_BROWSER_ACTION_MAC,
|
||||
|
||||
// Sent when an extension command shortcut for a page action is activated
|
||||
// on Mac. The source is the profile and the details is a std::pair of a
|
||||
// std::string containing an extension ID and a gfx::NativeWindow for the
|
||||
// associated window.
|
||||
NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC,
|
||||
|
||||
// A new extension RenderViewHost has been registered. The details are
|
||||
// the RenderViewHost*.
|
||||
NOTIFICATION_EXTENSION_VIEW_REGISTERED,
|
||||
|
||||
// An extension RenderViewHost has been unregistered. The details are
|
||||
// the RenderViewHost*.
|
||||
NOTIFICATION_EXTENSION_VIEW_UNREGISTERED,
|
||||
|
||||
// Sent by an extension to notify the browser about the results of a unit
|
||||
// test.
|
||||
NOTIFICATION_EXTENSION_TEST_PASSED,
|
||||
NOTIFICATION_EXTENSION_TEST_FAILED,
|
||||
|
||||
// Sent by extension test javascript code, typically in a browser test. The
|
||||
// sender is a std::string representing the extension id, and the details
|
||||
// are a std::string with some message. This is particularly useful when you
|
||||
// want to have C++ code wait for javascript code to do something.
|
||||
NOTIFICATION_EXTENSION_TEST_MESSAGE,
|
||||
|
||||
// Sent when an bookmarks extensions API function was successfully invoked.
|
||||
// The source is the id of the extension that invoked the function, and the
|
||||
// details are a pointer to the const BookmarksFunction in question.
|
||||
NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED,
|
||||
|
||||
// Sent when a downloads extensions API event is fired. The source is an
|
||||
// ExtensionDownloadsEventRouter::NotificationSource, and the details is a
|
||||
// std::string containing json. Used for testing.
|
||||
NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
|
||||
|
||||
// Sent when an omnibox extension has sent back omnibox suggestions. The
|
||||
// source is the profile, and the details are an
|
||||
// extensions::api::omnibox::SendSuggestions::Params object.
|
||||
NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY,
|
||||
|
||||
// Sent when the user accepts the input in an extension omnibox keyword
|
||||
// session. The source is the profile.
|
||||
NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED,
|
||||
|
||||
// Sent when an omnibox extension has updated the default suggestion. The
|
||||
// source is the profile.
|
||||
NOTIFICATION_EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED,
|
||||
|
||||
// Sent when the extension updater starts checking for updates to installed
|
||||
// extensions. The source is a Profile, and there are no details.
|
||||
NOTIFICATION_EXTENSION_UPDATING_STARTED,
|
||||
|
||||
// The extension updater found an update and will attempt to download and
|
||||
// install it. The source is a Profile, and the details are an
|
||||
// extensions::UpdateDetails object with the extension id and version of the
|
||||
// found update.
|
||||
NOTIFICATION_EXTENSION_UPDATE_FOUND,
|
||||
|
||||
// Upgrade notifications ---------------------------------------------------
|
||||
|
||||
// Sent when Chrome believes an update has been installed and available for
|
||||
// long enough with the user shutting down to let it take effect. See
|
||||
// upgrade_detector.cc for details on how long it waits. No details are
|
||||
// expected.
|
||||
NOTIFICATION_UPGRADE_RECOMMENDED,
|
||||
|
||||
// Sent when a critical update has been installed. No details are expected.
|
||||
NOTIFICATION_CRITICAL_UPGRADE_INSTALLED,
|
||||
|
||||
// Sent when the current install is outdated. No details are expected.
|
||||
NOTIFICATION_OUTDATED_INSTALL,
|
||||
|
||||
// Sent when the current install is outdated and auto-update (AU) is disabled.
|
||||
// No details are expected.
|
||||
NOTIFICATION_OUTDATED_INSTALL_NO_AU,
|
||||
|
||||
// Software incompatibility notifications ----------------------------------
|
||||
|
||||
// Sent when Chrome has finished compiling the list of loaded modules (and
|
||||
// other modules of interest). No details are expected.
|
||||
NOTIFICATION_MODULE_LIST_ENUMERATED,
|
||||
|
||||
// Sent when Chrome is done scanning the module list and when the user has
|
||||
// acknowledged the module incompatibility. No details are expected.
|
||||
NOTIFICATION_MODULE_INCOMPATIBILITY_BADGE_CHANGE,
|
||||
|
||||
// Content Settings --------------------------------------------------------
|
||||
|
||||
// Sent when content settings change. The source is a HostContentSettings
|
||||
// object, the details are ContentSettingsNotificationsDetails.
|
||||
NOTIFICATION_CONTENT_SETTINGS_CHANGED,
|
||||
|
||||
// Sent when the collect cookies dialog is shown. The source is a
|
||||
// TabSpecificContentSettings object, there are no details.
|
||||
NOTIFICATION_COLLECTED_COOKIES_SHOWN,
|
||||
|
||||
// Sent when a non-default setting in the the notification content settings
|
||||
// map has changed. The source is the DesktopNotificationService, the
|
||||
// details are None.
|
||||
NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
|
||||
|
||||
// Sent when content settings change for a tab. The source is a
|
||||
// content::WebContents object, the details are None.
|
||||
NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
|
||||
|
||||
// Sync --------------------------------------------------------------------
|
||||
|
||||
// The sync service has finished the datatype configuration process. The
|
||||
// source is the ProfileSyncService object of the Profile. There are no
|
||||
// details.
|
||||
NOTIFICATION_SYNC_CONFIGURE_DONE,
|
||||
|
||||
// A service is requesting a sync datatype refresh for the current profile.
|
||||
// The details value is a const syncer::ModelTypeSet.
|
||||
// If the payload map is empty, it should be treated as an invalidation for
|
||||
// all enabled types. This is used by session sync.
|
||||
NOTIFICATION_SYNC_REFRESH_LOCAL,
|
||||
|
||||
// External notification requesting a sync datatype refresh for the current
|
||||
// profile. The details value is a const syncer::ObjectIdInvalidationMap.
|
||||
// If the payload map is empty, it should be treated as an invalidation for
|
||||
// all enabled types. This is used for notifications on Android.
|
||||
NOTIFICATION_SYNC_REFRESH_REMOTE,
|
||||
|
||||
// The session service has been saved. This notification type is only sent
|
||||
// if there were new SessionService commands to save, and not for no-op save
|
||||
// operations.
|
||||
NOTIFICATION_SESSION_SERVICE_SAVED,
|
||||
|
||||
// A foreign session has been updated. If a new tab page is open, the
|
||||
// foreign session handler needs to update the new tab page's foreign
|
||||
// session data.
|
||||
NOTIFICATION_FOREIGN_SESSION_UPDATED,
|
||||
|
||||
// Foreign sessions has been disabled. New tabs should not display foreign
|
||||
// session data.
|
||||
NOTIFICATION_FOREIGN_SESSION_DISABLED,
|
||||
|
||||
// All tab metadata has been loaded from disk asynchronously.
|
||||
// Sent on the UI thread.
|
||||
// The source is the Profile. There are no details.
|
||||
NOTIFICATION_SESSION_RESTORE_COMPLETE,
|
||||
|
||||
// Cookies -----------------------------------------------------------------
|
||||
|
||||
// Sent when a cookie changes. The source is a Profile object, the details
|
||||
// are a ChromeCookieDetails object.
|
||||
NOTIFICATION_COOKIE_CHANGED,
|
||||
|
||||
// Download Notifications --------------------------------------------------
|
||||
|
||||
// Sent when a download is initiated. It is possible that the download will
|
||||
// not actually begin due to the DownloadRequestLimiter cancelling it
|
||||
// prematurely.
|
||||
// The source is the corresponding RenderViewHost. There are no details.
|
||||
NOTIFICATION_DOWNLOAD_INITIATED,
|
||||
|
||||
// Misc --------------------------------------------------------------------
|
||||
|
||||
// Sent when PerformanceMonitor has finished all the initial steps of data
|
||||
// collection and has begun passively observing. The source is the
|
||||
// PerformanceMonitor*. No details are expected.
|
||||
NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED,
|
||||
|
||||
#if defined(OS_CHROMEOS)
|
||||
// Sent when a chromium os user logs in.
|
||||
// The details are a chromeos::User object.
|
||||
NOTIFICATION_LOGIN_USER_CHANGED,
|
||||
|
||||
// Sent immediately after the logged-in user's profile is ready.
|
||||
// The details are a Profile object.
|
||||
NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
|
||||
|
||||
// Sent when the chromium session of a particular user is started.
|
||||
// If this is a new user on the machine this will not be sent until a profile
|
||||
// picture has been selected, unlike NOTIFICATION_LOGIN_USER_CHANGED which is
|
||||
// sent immediately after the user has logged in. This will be sent again if
|
||||
// the browser crashes and restarts.
|
||||
// The details are a chromeos::User object.
|
||||
NOTIFICATION_SESSION_STARTED,
|
||||
|
||||
// Sent when user image is updated.
|
||||
NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
|
||||
|
||||
// Sent by UserManager when a profile image download has been completed.
|
||||
NOTIFICATION_PROFILE_IMAGE_UPDATED,
|
||||
|
||||
// Sent by UserManager when profile image download has failed or user has the
|
||||
// default profile image or no profile image at all. No details are expected.
|
||||
NOTIFICATION_PROFILE_IMAGE_UPDATE_FAILED,
|
||||
|
||||
// Sent when a chromium os user attempts to log in. The source is
|
||||
// all and the details are AuthenticationNotificationDetails.
|
||||
NOTIFICATION_LOGIN_AUTHENTICATION,
|
||||
|
||||
// Sent when a network error message is displayed on the WebUI login screen.
|
||||
// First paint event of this fires NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE.
|
||||
NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN,
|
||||
|
||||
// Sent when the specific part of login/lock WebUI is considered to be
|
||||
// visible. That moment is tracked as the first paint event after one of the:
|
||||
// NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN
|
||||
//
|
||||
// Possible series of notifications:
|
||||
// 1. Boot into fresh OOBE
|
||||
// NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE
|
||||
// 2. Boot into user pods list (normal boot). Same for lock screen.
|
||||
// NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE
|
||||
// 3. Boot into GAIA sign in UI (user pods display disabled or no users):
|
||||
// if no network is connected or flaky network
|
||||
// (NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN +
|
||||
// NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE)
|
||||
// NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE
|
||||
// 4. Boot into retail mode
|
||||
// NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE
|
||||
// 5. Boot into kiosk mode
|
||||
// NOTIFICATION_KIOSK_APP_LAUNCHED
|
||||
NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
|
||||
|
||||
// Sent when proxy dialog is closed.
|
||||
NOTIFICATION_LOGIN_PROXY_CHANGED,
|
||||
|
||||
// Send when kiosk auto-launch warning screen is visible.
|
||||
NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
|
||||
|
||||
// Send when kiosk auto-launch warning screen had completed.
|
||||
NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED,
|
||||
|
||||
// Send when enable consumer kiosk warning screen is visible.
|
||||
NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
|
||||
|
||||
// Send when consumer kiosk has been enabled.
|
||||
NOTIFICATION_KIOSK_ENABLED,
|
||||
|
||||
// Send when enable consumer kiosk warning screen had completed.
|
||||
NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED,
|
||||
|
||||
// Sent when kiosk app list is loaded in UI.
|
||||
NOTIFICATION_KIOSK_APPS_LOADED,
|
||||
|
||||
// Sent when a kiosk app is launched.
|
||||
NOTIFICATION_KIOSK_APP_LAUNCHED,
|
||||
|
||||
// Sent when the user list has changed.
|
||||
NOTIFICATION_USER_LIST_CHANGED,
|
||||
|
||||
// Sent when the screen lock state has changed. The source is
|
||||
// ScreenLocker and the details is a bool specifing that the
|
||||
// screen is locked. When details is a false, the source object
|
||||
// is being deleted, so the receiver shouldn't use the screen locker
|
||||
// object.
|
||||
NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
|
||||
|
||||
// Sent by DeviceSettingsService to indicate that the ownership status
|
||||
// changed. If you can, please use DeviceSettingsService::Observer instead.
|
||||
// Other singleton-based services can't use that because Observer
|
||||
// unregistration is impossible due to unpredictable deletion order.
|
||||
NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
|
||||
|
||||
// Sent by SIM unlock dialog when it has finished with the process of
|
||||
// updating RequirePin setting. RequirePin setting might have been changed
|
||||
// to a new value or update might have been canceled.
|
||||
// In either case notification is sent and details contain a bool
|
||||
// that represents current value.
|
||||
NOTIFICATION_REQUIRE_PIN_SETTING_CHANGE_ENDED,
|
||||
|
||||
// Sent by SIM unlock dialog when it has finished the EnterPin or
|
||||
// EnterPuk dialog, either because the user cancelled, or entered a
|
||||
// PIN or PUK.
|
||||
NOTIFICATION_ENTER_PIN_ENDED,
|
||||
#endif
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
// Sent when a bookmark's context menu is shown. Used to notify
|
||||
// tests that the context menu has been created and shown.
|
||||
NOTIFICATION_BOOKMARK_CONTEXT_MENU_SHOWN,
|
||||
|
||||
// Notification that the nested loop using during tab dragging has returned.
|
||||
// Used for testing.
|
||||
NOTIFICATION_TAB_DRAG_LOOP_DONE,
|
||||
#endif
|
||||
|
||||
// Send when a context menu is shown. Used to notify tests that the context
|
||||
// menu has been created and shown.
|
||||
NOTIFICATION_RENDER_VIEW_CONTEXT_MENU_SHOWN,
|
||||
|
||||
// Sent when the Instant Controller determines whether an Instant tab supports
|
||||
// the Instant API or not.
|
||||
NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
|
||||
|
||||
// Sent when the Instant Controller determines whether the NTP supports the
|
||||
// Instant API or not.
|
||||
NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED,
|
||||
|
||||
// Sent when the CaptivePortalService checks if we're behind a captive portal.
|
||||
// The Source is the Profile the CaptivePortalService belongs to, and the
|
||||
// Details are a Details<CaptivePortalService::CheckResults>.
|
||||
NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
|
||||
|
||||
// Sent when the applications in the NTP app launcher have been reordered.
|
||||
// The details, if not NoDetails, is the std::string ID of the extension that
|
||||
// was moved.
|
||||
NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
|
||||
|
||||
// Sent when an app is installed and an NTP has been shown. Source is the
|
||||
// WebContents that was shown, and Details is the string ID of the extension
|
||||
// which was installed.
|
||||
NOTIFICATION_APP_INSTALLED_TO_NTP,
|
||||
|
||||
// Similar to NOTIFICATION_APP_INSTALLED_TO_NTP but used to nofity ash AppList
|
||||
// about installed app. Source is the profile in which the app is installed
|
||||
// and Details is the string ID of the extension.
|
||||
NOTIFICATION_APP_INSTALLED_TO_APPLIST,
|
||||
|
||||
#if defined(USE_ASH)
|
||||
// Sent when wallpaper show animation has finished.
|
||||
NOTIFICATION_WALLPAPER_ANIMATION_FINISHED,
|
||||
|
||||
// Sent when the Ash session has started. In its current incantation this is
|
||||
// generated when the metro app has connected to the browser IPC channel.
|
||||
// Used only on Windows.
|
||||
NOTIFICATION_ASH_SESSION_STARTED,
|
||||
// Sent when the Ash session ended. Currently this means the metro app exited.
|
||||
// Used only on Windows.
|
||||
NOTIFICATION_ASH_SESSION_ENDED,
|
||||
#endif
|
||||
|
||||
// Protocol Handler Registry -----------------------------------------------
|
||||
// Sent when a ProtocolHandlerRegistry is changed. The source is the profile.
|
||||
NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED,
|
||||
|
||||
// Sent when the cached profile info has changed.
|
||||
NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
|
||||
|
||||
// Sent when the cached profile has finished writing a profile picture to
|
||||
// disk.
|
||||
NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED,
|
||||
|
||||
// Sent when the browser enters or exits fullscreen mode.
|
||||
NOTIFICATION_FULLSCREEN_CHANGED,
|
||||
|
||||
// Sent when the FullscreenController changes, confirms, or denies mouse lock.
|
||||
// The source is the browser's FullscreenController, no details.
|
||||
NOTIFICATION_MOUSE_LOCK_CHANGED,
|
||||
|
||||
// Sent by the PluginPrefs when there is a change of plugin enable/disable
|
||||
// status. The source is the profile.
|
||||
NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
|
||||
|
||||
// Panels Notifications. The Panels are small browser windows near the bottom
|
||||
// of the screen.
|
||||
// Sent when all nonblocking bounds animations are finished across panels.
|
||||
// Used only in unit testing.
|
||||
NOTIFICATION_PANEL_BOUNDS_ANIMATIONS_FINISHED,
|
||||
|
||||
// Sent when panel gains/loses focus.
|
||||
// The source is the Panel, no details.
|
||||
// Used only in unit testing.
|
||||
NOTIFICATION_PANEL_CHANGED_ACTIVE_STATUS,
|
||||
|
||||
// Sent when panel is minimized/restored/shows title only etc.
|
||||
// The source is the Panel, no details.
|
||||
NOTIFICATION_PANEL_CHANGED_EXPANSION_STATE,
|
||||
|
||||
// Sent when panel window size is known. This is for platforms where the
|
||||
// window creation is async and size of the window only becomes known later.
|
||||
// Used only in unit testing.
|
||||
NOTIFICATION_PANEL_WINDOW_SIZE_KNOWN,
|
||||
|
||||
// Sent when panel app icon is loaded.
|
||||
// Used only in unit testing.
|
||||
NOTIFICATION_PANEL_APP_ICON_LOADED,
|
||||
|
||||
// Sent when panel collection get updated.
|
||||
// The source is the PanelCollection, no details.
|
||||
// Used only in coordination with notification balloons.
|
||||
NOTIFICATION_PANEL_COLLECTION_UPDATED,
|
||||
|
||||
// Sent when panel is closed.
|
||||
// The source is the Panel, no details.
|
||||
NOTIFICATION_PANEL_CLOSED,
|
||||
|
||||
// Sent when a global error has changed and the error UI should update it
|
||||
// self. The source is a Source<Profile> containing the profile for the
|
||||
// error. The detail is a GlobalError object that has changed or NULL if
|
||||
// all error UIs should update.
|
||||
NOTIFICATION_GLOBAL_ERRORS_CHANGED,
|
||||
|
||||
// BrowsingDataRemover ----------------------------------------------------
|
||||
// Sent on the UI thread after BrowsingDataRemover has removed browsing data
|
||||
// but before it has notified its explicit observers. The source is a
|
||||
// Source<Profile> containing the profile in which browsing data was removed,
|
||||
// and the detail is a BrowsingDataRemover::NotificationDetail containing the
|
||||
// removal mask and the start of the removal timeframe with which
|
||||
// BrowsingDataRemove::Remove was called.
|
||||
NOTIFICATION_BROWSING_DATA_REMOVED,
|
||||
|
||||
// The user accepted or dismissed a SSL client authentication request.
|
||||
// The source is a Source<net::HttpNetworkSession>. Details is a
|
||||
// (std::pair<net::SSLCertRequestInfo*, net::X509Certificate*>).
|
||||
NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED,
|
||||
|
||||
// Session Restore --------------------------------------------------------
|
||||
|
||||
// Sent when synchronous (startup) session restore completes. No details or
|
||||
// source.
|
||||
NOTIFICATION_SESSION_RESTORE_DONE,
|
||||
|
||||
// Note:-
|
||||
// Currently only Content and Chrome define and use notifications.
|
||||
// Custom notifications not belonging to Content and Chrome should start
|
||||
// from here.
|
||||
NOTIFICATION_CHROME_END,
|
||||
};
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_BROWSER_CHROME_NOTIFICATION_TYPES_H_
|
363
chromium_src/chrome/browser/printing/print_job.cc
Normal file
363
chromium_src/chrome/browser/printing/print_job.cc
Normal file
|
@ -0,0 +1,363 @@
|
|||
// Copyright (c) 2012 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/printing/print_job.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/bind_helpers.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "base/threading/worker_pool.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "chrome/browser/chrome_notification_types.h"
|
||||
#include "chrome/browser/printing/print_job_worker.h"
|
||||
#include "content/public/browser/notification_service.h"
|
||||
#include "printing/printed_document.h"
|
||||
#include "printing/printed_page.h"
|
||||
|
||||
using base::TimeDelta;
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper function to ensure |owner| is valid until at least |callback| returns.
|
||||
void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
|
||||
const base::Closure& callback) {
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace printing {
|
||||
|
||||
PrintJob::PrintJob()
|
||||
: ui_message_loop_(base::MessageLoop::current()),
|
||||
source_(NULL),
|
||||
worker_(),
|
||||
settings_(),
|
||||
is_job_pending_(false),
|
||||
is_canceling_(false),
|
||||
quit_factory_(this) {
|
||||
DCHECK(ui_message_loop_);
|
||||
// This is normally a UI message loop, but in unit tests, the message loop is
|
||||
// of the 'default' type.
|
||||
DCHECK(base::MessageLoopForUI::IsCurrent() ||
|
||||
ui_message_loop_->type() == base::MessageLoop::TYPE_DEFAULT);
|
||||
ui_message_loop_->AddDestructionObserver(this);
|
||||
}
|
||||
|
||||
PrintJob::~PrintJob() {
|
||||
ui_message_loop_->RemoveDestructionObserver(this);
|
||||
// The job should be finished (or at least canceled) when it is destroyed.
|
||||
DCHECK(!is_job_pending_);
|
||||
DCHECK(!is_canceling_);
|
||||
if (worker_.get())
|
||||
DCHECK(worker_->message_loop() == NULL);
|
||||
DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
|
||||
}
|
||||
|
||||
void PrintJob::Initialize(PrintJobWorkerOwner* job,
|
||||
PrintedPagesSource* source,
|
||||
int page_count) {
|
||||
DCHECK(!source_);
|
||||
DCHECK(!worker_.get());
|
||||
DCHECK(!is_job_pending_);
|
||||
DCHECK(!is_canceling_);
|
||||
DCHECK(!document_.get());
|
||||
source_ = source;
|
||||
worker_.reset(job->DetachWorker(this));
|
||||
settings_ = job->settings();
|
||||
|
||||
PrintedDocument* new_doc =
|
||||
new PrintedDocument(settings_, source_, job->cookie());
|
||||
new_doc->set_page_count(page_count);
|
||||
UpdatePrintedDocument(new_doc);
|
||||
|
||||
// Don't forget to register to our own messages.
|
||||
registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
content::Source<PrintJob>(this));
|
||||
}
|
||||
|
||||
void PrintJob::Observe(int type,
|
||||
const content::NotificationSource& source,
|
||||
const content::NotificationDetails& details) {
|
||||
DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
|
||||
switch (type) {
|
||||
case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
|
||||
OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJob::GetSettingsDone(const PrintSettings& new_settings,
|
||||
PrintingContext::Result result) {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
PrintJobWorker* PrintJob::DetachWorker(PrintJobWorkerOwner* new_owner) {
|
||||
NOTREACHED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base::MessageLoop* PrintJob::message_loop() {
|
||||
return ui_message_loop_;
|
||||
}
|
||||
|
||||
const PrintSettings& PrintJob::settings() const {
|
||||
return settings_;
|
||||
}
|
||||
|
||||
int PrintJob::cookie() const {
|
||||
if (!document_.get())
|
||||
// Always use an invalid cookie in this case.
|
||||
return 0;
|
||||
return document_->cookie();
|
||||
}
|
||||
|
||||
void PrintJob::WillDestroyCurrentMessageLoop() {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void PrintJob::StartPrinting() {
|
||||
DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
|
||||
DCHECK(worker_->message_loop());
|
||||
DCHECK(!is_job_pending_);
|
||||
if (!worker_->message_loop() || is_job_pending_)
|
||||
return;
|
||||
|
||||
// Real work is done in PrintJobWorker::StartPrinting().
|
||||
worker_->message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&HoldRefCallback, make_scoped_refptr(this),
|
||||
base::Bind(&PrintJobWorker::StartPrinting,
|
||||
base::Unretained(worker_.get()), document_)));
|
||||
// Set the flag right now.
|
||||
is_job_pending_ = true;
|
||||
|
||||
// Tell everyone!
|
||||
scoped_refptr<JobEventDetails> details(
|
||||
new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL));
|
||||
content::NotificationService::current()->Notify(
|
||||
chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
content::Source<PrintJob>(this),
|
||||
content::Details<JobEventDetails>(details.get()));
|
||||
}
|
||||
|
||||
void PrintJob::Stop() {
|
||||
DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
|
||||
|
||||
if (quit_factory_.HasWeakPtrs()) {
|
||||
// In case we're running a nested message loop to wait for a job to finish,
|
||||
// and we finished before the timeout, quit the nested loop right away.
|
||||
Quit();
|
||||
quit_factory_.InvalidateWeakPtrs();
|
||||
}
|
||||
|
||||
// Be sure to live long enough.
|
||||
scoped_refptr<PrintJob> handle(this);
|
||||
|
||||
if (worker_->message_loop()) {
|
||||
ControlledWorkerShutdown();
|
||||
} else {
|
||||
// Flush the cached document.
|
||||
UpdatePrintedDocument(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJob::Cancel() {
|
||||
if (is_canceling_)
|
||||
return;
|
||||
is_canceling_ = true;
|
||||
|
||||
// Be sure to live long enough.
|
||||
scoped_refptr<PrintJob> handle(this);
|
||||
|
||||
DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
|
||||
base::MessageLoop* worker_loop =
|
||||
worker_.get() ? worker_->message_loop() : NULL;
|
||||
if (worker_loop) {
|
||||
// Call this right now so it renders the context invalid. Do not use
|
||||
// InvokeLater since it would take too much time.
|
||||
worker_->Cancel();
|
||||
}
|
||||
// Make sure a Cancel() is broadcast.
|
||||
scoped_refptr<JobEventDetails> details(
|
||||
new JobEventDetails(JobEventDetails::FAILED, NULL, NULL));
|
||||
content::NotificationService::current()->Notify(
|
||||
chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
content::Source<PrintJob>(this),
|
||||
content::Details<JobEventDetails>(details.get()));
|
||||
Stop();
|
||||
is_canceling_ = false;
|
||||
}
|
||||
|
||||
bool PrintJob::FlushJob(base::TimeDelta timeout) {
|
||||
// Make sure the object outlive this message loop.
|
||||
scoped_refptr<PrintJob> handle(this);
|
||||
|
||||
base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
|
||||
base::Bind(&PrintJob::Quit, quit_factory_.GetWeakPtr()), timeout);
|
||||
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||
base::MessageLoop::current());
|
||||
base::MessageLoop::current()->Run();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrintJob::DisconnectSource() {
|
||||
source_ = NULL;
|
||||
if (document_.get())
|
||||
document_->DisconnectSource();
|
||||
}
|
||||
|
||||
bool PrintJob::is_job_pending() const {
|
||||
return is_job_pending_;
|
||||
}
|
||||
|
||||
PrintedDocument* PrintJob::document() const {
|
||||
return document_.get();
|
||||
}
|
||||
|
||||
void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) {
|
||||
if (document_.get() == new_document)
|
||||
return;
|
||||
|
||||
document_ = new_document;
|
||||
|
||||
if (document_.get()) {
|
||||
settings_ = document_->settings();
|
||||
}
|
||||
|
||||
if (worker_.get() && worker_->message_loop()) {
|
||||
DCHECK(!is_job_pending_);
|
||||
// Sync the document with the worker.
|
||||
worker_->message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&HoldRefCallback, make_scoped_refptr(this),
|
||||
base::Bind(&PrintJobWorker::OnDocumentChanged,
|
||||
base::Unretained(worker_.get()), document_)));
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
|
||||
switch (event_details.type()) {
|
||||
case JobEventDetails::FAILED: {
|
||||
settings_.Clear();
|
||||
// No need to cancel since the worker already canceled itself.
|
||||
Stop();
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::USER_INIT_DONE:
|
||||
case JobEventDetails::DEFAULT_INIT_DONE:
|
||||
case JobEventDetails::USER_INIT_CANCELED: {
|
||||
DCHECK_EQ(event_details.document(), document_.get());
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::NEW_DOC:
|
||||
case JobEventDetails::NEW_PAGE:
|
||||
case JobEventDetails::PAGE_DONE:
|
||||
case JobEventDetails::JOB_DONE:
|
||||
case JobEventDetails::ALL_PAGES_REQUESTED: {
|
||||
// Don't care.
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::DOC_DONE: {
|
||||
// This will call Stop() and broadcast a JOB_DONE message.
|
||||
base::MessageLoop::current()->PostTask(
|
||||
FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJob::OnDocumentDone() {
|
||||
// Be sure to live long enough. The instance could be destroyed by the
|
||||
// JOB_DONE broadcast.
|
||||
scoped_refptr<PrintJob> handle(this);
|
||||
|
||||
// Stop the worker thread.
|
||||
Stop();
|
||||
|
||||
scoped_refptr<JobEventDetails> details(
|
||||
new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), NULL));
|
||||
content::NotificationService::current()->Notify(
|
||||
chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
content::Source<PrintJob>(this),
|
||||
content::Details<JobEventDetails>(details.get()));
|
||||
}
|
||||
|
||||
void PrintJob::ControlledWorkerShutdown() {
|
||||
DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
|
||||
|
||||
// The deadlock this code works around is specific to window messaging on
|
||||
// Windows, so we aren't likely to need it on any other platforms.
|
||||
#if defined(OS_WIN)
|
||||
// We could easily get into a deadlock case if worker_->Stop() is used; the
|
||||
// printer driver created a window as a child of the browser window. By
|
||||
// canceling the job, the printer driver initiated dialog box is destroyed,
|
||||
// which sends a blocking message to its parent window. If the browser window
|
||||
// thread is not processing messages, a deadlock occurs.
|
||||
//
|
||||
// This function ensures that the dialog box will be destroyed in a timely
|
||||
// manner by the mere fact that the thread will terminate. So the potential
|
||||
// deadlock is eliminated.
|
||||
worker_->StopSoon();
|
||||
|
||||
// Delay shutdown until the worker terminates. We want this code path
|
||||
// to wait on the thread to quit before continuing.
|
||||
if (worker_->IsRunning()) {
|
||||
base::MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&PrintJob::ControlledWorkerShutdown, this),
|
||||
base::TimeDelta::FromMilliseconds(100));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Now make sure the thread object is cleaned up. Do this on a worker
|
||||
// thread because it may block.
|
||||
base::WorkerPool::PostTaskAndReply(
|
||||
FROM_HERE,
|
||||
base::Bind(&PrintJobWorker::Stop, base::Unretained(worker_.get())),
|
||||
base::Bind(&PrintJob::HoldUntilStopIsCalled, this),
|
||||
false);
|
||||
|
||||
is_job_pending_ = false;
|
||||
registrar_.RemoveAll();
|
||||
UpdatePrintedDocument(NULL);
|
||||
}
|
||||
|
||||
void PrintJob::HoldUntilStopIsCalled() {
|
||||
}
|
||||
|
||||
void PrintJob::Quit() {
|
||||
base::MessageLoop::current()->Quit();
|
||||
}
|
||||
|
||||
// Takes settings_ ownership and will be deleted in the receiving thread.
|
||||
JobEventDetails::JobEventDetails(Type type,
|
||||
PrintedDocument* document,
|
||||
PrintedPage* page)
|
||||
: document_(document),
|
||||
page_(page),
|
||||
type_(type) {
|
||||
}
|
||||
|
||||
JobEventDetails::~JobEventDetails() {
|
||||
}
|
||||
|
||||
PrintedDocument* JobEventDetails::document() const { return document_.get(); }
|
||||
|
||||
PrintedPage* JobEventDetails::page() const { return page_.get(); }
|
||||
|
||||
} // namespace printing
|
212
chromium_src/chrome/browser/printing/print_job.h
Normal file
212
chromium_src/chrome/browser/printing/print_job.h
Normal file
|
@ -0,0 +1,212 @@
|
|||
// Copyright (c) 2012 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_PRINTING_PRINT_JOB_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINT_JOB_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "chrome/browser/printing/print_job_worker_owner.h"
|
||||
#include "content/public/browser/notification_observer.h"
|
||||
#include "content/public/browser/notification_registrar.h"
|
||||
|
||||
class Thread;
|
||||
|
||||
namespace printing {
|
||||
|
||||
// See definition below.
|
||||
class JobEventDetails;
|
||||
|
||||
class PrintedDocument;
|
||||
class PrintedPage;
|
||||
class PrintedPagesSource;
|
||||
class PrintJobWorker;
|
||||
class PrinterQuery;
|
||||
|
||||
// Manages the print work for a specific document. Talks to the printer through
|
||||
// PrintingContext through PrintJobWorker. Hides access to PrintingContext in a
|
||||
// worker thread so the caller never blocks. PrintJob will send notifications on
|
||||
// any state change. While printing, the PrintJobManager instance keeps a
|
||||
// reference to the job to be sure it is kept alive. All the code in this class
|
||||
// runs in the UI thread.
|
||||
class PrintJob : public PrintJobWorkerOwner,
|
||||
public content::NotificationObserver,
|
||||
public base::MessageLoop::DestructionObserver {
|
||||
public:
|
||||
// Create a empty PrintJob. When initializing with this constructor,
|
||||
// post-constructor initialization must be done with Initialize().
|
||||
PrintJob();
|
||||
|
||||
// Grabs the ownership of the PrintJobWorker from another job, which is
|
||||
// usually a PrinterQuery. Set the expected page count of the print job.
|
||||
void Initialize(PrintJobWorkerOwner* job, PrintedPagesSource* source,
|
||||
int page_count);
|
||||
|
||||
// content::NotificationObserver implementation.
|
||||
virtual void Observe(int type,
|
||||
const content::NotificationSource& source,
|
||||
const content::NotificationDetails& details) OVERRIDE;
|
||||
|
||||
// PrintJobWorkerOwner implementation.
|
||||
virtual void GetSettingsDone(const PrintSettings& new_settings,
|
||||
PrintingContext::Result result) OVERRIDE;
|
||||
virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) OVERRIDE;
|
||||
virtual base::MessageLoop* message_loop() OVERRIDE;
|
||||
virtual const PrintSettings& settings() const OVERRIDE;
|
||||
virtual int cookie() const OVERRIDE;
|
||||
|
||||
// DestructionObserver implementation.
|
||||
virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
|
||||
|
||||
// Starts the actual printing. Signals the worker that it should begin to
|
||||
// spool as soon as data is available.
|
||||
void StartPrinting();
|
||||
|
||||
// Asks for the worker thread to finish its queued tasks and disconnects the
|
||||
// delegate object. The PrintJobManager will remove its reference. This may
|
||||
// have the side-effect of destroying the object if the caller doesn't have a
|
||||
// handle to the object. Use PrintJob::is_stopped() to check whether the
|
||||
// worker thread has actually stopped.
|
||||
void Stop();
|
||||
|
||||
// Cancels printing job and stops the worker thread. Takes effect immediately.
|
||||
void Cancel();
|
||||
|
||||
// Synchronously wait for the job to finish. It is mainly useful when the
|
||||
// process is about to be shut down and we're waiting for the spooler to eat
|
||||
// our data.
|
||||
bool FlushJob(base::TimeDelta timeout);
|
||||
|
||||
// Disconnects the PrintedPage source (PrintedPagesSource). It is done when
|
||||
// the source is being destroyed.
|
||||
void DisconnectSource();
|
||||
|
||||
// Returns true if the print job is pending, i.e. between a StartPrinting()
|
||||
// and the end of the spooling.
|
||||
bool is_job_pending() const;
|
||||
|
||||
// Access the current printed document. Warning: may be NULL.
|
||||
PrintedDocument* document() const;
|
||||
|
||||
protected:
|
||||
virtual ~PrintJob();
|
||||
|
||||
private:
|
||||
// Updates document_ to a new instance.
|
||||
void UpdatePrintedDocument(PrintedDocument* new_document);
|
||||
|
||||
// Processes a NOTIFY_PRINT_JOB_EVENT notification.
|
||||
void OnNotifyPrintJobEvent(const JobEventDetails& event_details);
|
||||
|
||||
// Releases the worker thread by calling Stop(), then broadcasts a JOB_DONE
|
||||
// notification.
|
||||
void OnDocumentDone();
|
||||
|
||||
// Terminates the worker thread in a very controlled way, to work around any
|
||||
// eventual deadlock.
|
||||
void ControlledWorkerShutdown();
|
||||
|
||||
// Called at shutdown when running a nested message loop.
|
||||
void Quit();
|
||||
|
||||
void HoldUntilStopIsCalled();
|
||||
|
||||
content::NotificationRegistrar registrar_;
|
||||
|
||||
// Main message loop reference. Used to send notifications in the right
|
||||
// thread.
|
||||
base::MessageLoop* const ui_message_loop_;
|
||||
|
||||
// Source that generates the PrintedPage's (i.e. a WebContents). It will be
|
||||
// set back to NULL if the source is deleted before this object.
|
||||
PrintedPagesSource* source_;
|
||||
|
||||
// All the UI is done in a worker thread because many Win32 print functions
|
||||
// are blocking and enters a message loop without your consent. There is one
|
||||
// worker thread per print job.
|
||||
scoped_ptr<PrintJobWorker> worker_;
|
||||
|
||||
// Cache of the print context settings for access in the UI thread.
|
||||
PrintSettings settings_;
|
||||
|
||||
// The printed document.
|
||||
scoped_refptr<PrintedDocument> document_;
|
||||
|
||||
// Is the worker thread printing.
|
||||
bool is_job_pending_;
|
||||
|
||||
// Is Canceling? If so, try to not cause recursion if on FAILED notification,
|
||||
// the notified calls Cancel() again.
|
||||
bool is_canceling_;
|
||||
|
||||
// Used at shutdown so that we can quit a nested message loop.
|
||||
base::WeakPtrFactory<PrintJob> quit_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintJob);
|
||||
};
|
||||
|
||||
// Details for a NOTIFY_PRINT_JOB_EVENT notification. The members may be NULL.
|
||||
class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
|
||||
public:
|
||||
// Event type.
|
||||
enum Type {
|
||||
// Print... dialog box has been closed with OK button.
|
||||
USER_INIT_DONE,
|
||||
|
||||
// Print... dialog box has been closed with CANCEL button.
|
||||
USER_INIT_CANCELED,
|
||||
|
||||
// An automated initialization has been done, e.g. Init(false, NULL).
|
||||
DEFAULT_INIT_DONE,
|
||||
|
||||
// A new document started printing.
|
||||
NEW_DOC,
|
||||
|
||||
// A new page started printing.
|
||||
NEW_PAGE,
|
||||
|
||||
// A page is done printing.
|
||||
PAGE_DONE,
|
||||
|
||||
// A document is done printing. The worker thread is still alive. Warning:
|
||||
// not a good moment to release the handle to PrintJob.
|
||||
DOC_DONE,
|
||||
|
||||
// The worker thread is finished. A good moment to release the handle to
|
||||
// PrintJob.
|
||||
JOB_DONE,
|
||||
|
||||
// All missing pages have been requested.
|
||||
ALL_PAGES_REQUESTED,
|
||||
|
||||
// An error occured. Printing is canceled.
|
||||
FAILED,
|
||||
};
|
||||
|
||||
JobEventDetails(Type type, PrintedDocument* document, PrintedPage* page);
|
||||
|
||||
// Getters.
|
||||
PrintedDocument* document() const;
|
||||
PrintedPage* page() const;
|
||||
Type type() const {
|
||||
return type_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<JobEventDetails>;
|
||||
|
||||
~JobEventDetails();
|
||||
|
||||
scoped_refptr<PrintedDocument> document_;
|
||||
scoped_refptr<PrintedPage> page_;
|
||||
const Type type_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(JobEventDetails);
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_H_
|
159
chromium_src/chrome/browser/printing/print_job_manager.cc
Normal file
159
chromium_src/chrome/browser/printing/print_job_manager.cc
Normal file
|
@ -0,0 +1,159 @@
|
|||
// Copyright (c) 2012 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/printing/print_job_manager.h"
|
||||
|
||||
#include "chrome/browser/chrome_notification_types.h"
|
||||
#include "chrome/browser/printing/print_job.h"
|
||||
#include "chrome/browser/printing/printer_query.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/notification_service.h"
|
||||
#include "printing/printed_document.h"
|
||||
#include "printing/printed_page.h"
|
||||
|
||||
namespace printing {
|
||||
|
||||
PrintQueriesQueue::PrintQueriesQueue() {
|
||||
}
|
||||
|
||||
PrintQueriesQueue::~PrintQueriesQueue() {
|
||||
base::AutoLock lock(lock_);
|
||||
queued_queries_.clear();
|
||||
}
|
||||
|
||||
void PrintQueriesQueue::SetDestination(PrintDestinationInterface* destination) {
|
||||
base::AutoLock lock(lock_);
|
||||
destination_ = destination;
|
||||
}
|
||||
|
||||
void PrintQueriesQueue::QueuePrinterQuery(PrinterQuery* job) {
|
||||
base::AutoLock lock(lock_);
|
||||
DCHECK(job);
|
||||
queued_queries_.push_back(make_scoped_refptr(job));
|
||||
DCHECK(job->is_valid());
|
||||
}
|
||||
|
||||
scoped_refptr<PrinterQuery> PrintQueriesQueue::PopPrinterQuery(
|
||||
int document_cookie) {
|
||||
base::AutoLock lock(lock_);
|
||||
for (PrinterQueries::iterator itr = queued_queries_.begin();
|
||||
itr != queued_queries_.end(); ++itr) {
|
||||
if ((*itr)->cookie() == document_cookie && !(*itr)->is_callback_pending()) {
|
||||
scoped_refptr<printing::PrinterQuery> current_query(*itr);
|
||||
queued_queries_.erase(itr);
|
||||
DCHECK(current_query->is_valid());
|
||||
return current_query;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scoped_refptr<PrinterQuery> PrintQueriesQueue::CreatePrinterQuery() {
|
||||
scoped_refptr<PrinterQuery> job = new printing::PrinterQuery;
|
||||
base::AutoLock lock(lock_);
|
||||
job->SetWorkerDestination(destination_);
|
||||
return job;
|
||||
}
|
||||
|
||||
void PrintQueriesQueue::Shutdown() {
|
||||
base::AutoLock lock(lock_);
|
||||
queued_queries_.clear();
|
||||
destination_ = NULL;
|
||||
}
|
||||
|
||||
PrintJobManager::PrintJobManager() : is_shutdown_(false) {
|
||||
registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
content::NotificationService::AllSources());
|
||||
}
|
||||
|
||||
PrintJobManager::~PrintJobManager() {
|
||||
}
|
||||
|
||||
scoped_refptr<PrintQueriesQueue> PrintJobManager::queue() {
|
||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
||||
if (!queue_)
|
||||
queue_ = new PrintQueriesQueue();
|
||||
return queue_;
|
||||
}
|
||||
|
||||
void PrintJobManager::Shutdown() {
|
||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
||||
DCHECK(!is_shutdown_);
|
||||
is_shutdown_ = true;
|
||||
registrar_.RemoveAll();
|
||||
StopJobs(true);
|
||||
if (queue_)
|
||||
queue_->Shutdown();
|
||||
queue_ = NULL;
|
||||
}
|
||||
|
||||
void PrintJobManager::StopJobs(bool wait_for_finish) {
|
||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
||||
// Copy the array since it can be modified in transit.
|
||||
PrintJobs to_stop;
|
||||
to_stop.swap(current_jobs_);
|
||||
|
||||
for (PrintJobs::const_iterator job = to_stop.begin(); job != to_stop.end();
|
||||
++job) {
|
||||
// Wait for two minutes for the print job to be spooled.
|
||||
if (wait_for_finish)
|
||||
(*job)->FlushJob(base::TimeDelta::FromMinutes(2));
|
||||
(*job)->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJobManager::Observe(int type,
|
||||
const content::NotificationSource& source,
|
||||
const content::NotificationDetails& details) {
|
||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
||||
switch (type) {
|
||||
case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
|
||||
OnPrintJobEvent(content::Source<PrintJob>(source).ptr(),
|
||||
*content::Details<JobEventDetails>(details).ptr());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJobManager::OnPrintJobEvent(
|
||||
PrintJob* print_job,
|
||||
const JobEventDetails& event_details) {
|
||||
switch (event_details.type()) {
|
||||
case JobEventDetails::NEW_DOC: {
|
||||
DCHECK(current_jobs_.end() == current_jobs_.find(print_job));
|
||||
// Causes a AddRef().
|
||||
current_jobs_.insert(print_job);
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::JOB_DONE: {
|
||||
DCHECK(current_jobs_.end() != current_jobs_.find(print_job));
|
||||
current_jobs_.erase(print_job);
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::FAILED: {
|
||||
current_jobs_.erase(print_job);
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::USER_INIT_DONE:
|
||||
case JobEventDetails::USER_INIT_CANCELED:
|
||||
case JobEventDetails::DEFAULT_INIT_DONE:
|
||||
case JobEventDetails::NEW_PAGE:
|
||||
case JobEventDetails::PAGE_DONE:
|
||||
case JobEventDetails::DOC_DONE:
|
||||
case JobEventDetails::ALL_PAGES_REQUESTED: {
|
||||
// Don't care.
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace printing
|
104
chromium_src/chrome/browser/printing/print_job_manager.h
Normal file
104
chromium_src/chrome/browser/printing/print_job_manager.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
// Copyright (c) 2012 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_PRINTING_PRINT_JOB_MANAGER_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINT_JOB_MANAGER_H_
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "base/threading/non_thread_safe.h"
|
||||
#include "content/public/browser/notification_observer.h"
|
||||
#include "content/public/browser/notification_registrar.h"
|
||||
#include "printing/print_destination_interface.h"
|
||||
|
||||
namespace printing {
|
||||
|
||||
class JobEventDetails;
|
||||
class PrintJob;
|
||||
class PrinterQuery;
|
||||
|
||||
class PrintQueriesQueue : public base::RefCountedThreadSafe<PrintQueriesQueue> {
|
||||
public:
|
||||
PrintQueriesQueue();
|
||||
|
||||
// Sets the print destination to be set on the next print job.
|
||||
void SetDestination(PrintDestinationInterface* destination);
|
||||
|
||||
// Queues a semi-initialized worker thread. Can be called from any thread.
|
||||
// Current use case is queuing from the I/O thread.
|
||||
// TODO(maruel): Have them vanish after a timeout (~5 minutes?)
|
||||
void QueuePrinterQuery(PrinterQuery* job);
|
||||
|
||||
// Pops a queued PrintJobWorkerOwner object that was previously queued or
|
||||
// create new one. Can be called from any thread.
|
||||
scoped_refptr<PrinterQuery> PopPrinterQuery(int document_cookie);
|
||||
|
||||
// Creates new query.
|
||||
scoped_refptr<PrinterQuery> CreatePrinterQuery();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<PrintQueriesQueue>;
|
||||
typedef std::vector<scoped_refptr<PrinterQuery> > PrinterQueries;
|
||||
|
||||
virtual ~PrintQueriesQueue();
|
||||
|
||||
// Used to serialize access to queued_workers_.
|
||||
base::Lock lock_;
|
||||
|
||||
PrinterQueries queued_queries_;
|
||||
|
||||
scoped_refptr<PrintDestinationInterface> destination_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintQueriesQueue);
|
||||
};
|
||||
|
||||
class PrintJobManager : public content::NotificationObserver {
|
||||
public:
|
||||
PrintJobManager();
|
||||
virtual ~PrintJobManager();
|
||||
|
||||
// On browser quit, we should wait to have the print job finished.
|
||||
void Shutdown();
|
||||
|
||||
// content::NotificationObserver
|
||||
virtual void Observe(int type,
|
||||
const content::NotificationSource& source,
|
||||
const content::NotificationDetails& details) OVERRIDE;
|
||||
|
||||
// Returns queries queue. Never returns NULL. Must be called on Browser UI
|
||||
// Thread. Reference could be stored and used from any thread.
|
||||
scoped_refptr<PrintQueriesQueue> queue();
|
||||
|
||||
private:
|
||||
typedef std::set<scoped_refptr<PrintJob> > PrintJobs;
|
||||
|
||||
// Processes a NOTIFY_PRINT_JOB_EVENT notification.
|
||||
void OnPrintJobEvent(PrintJob* print_job,
|
||||
const JobEventDetails& event_details);
|
||||
|
||||
// Stops all printing jobs. If wait_for_finish is true, tries to give jobs
|
||||
// a chance to complete before stopping them.
|
||||
void StopJobs(bool wait_for_finish);
|
||||
|
||||
content::NotificationRegistrar registrar_;
|
||||
|
||||
// Current print jobs that are active.
|
||||
PrintJobs current_jobs_;
|
||||
|
||||
scoped_refptr<PrintQueriesQueue> queue_;
|
||||
|
||||
bool is_shutdown_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintJobManager);
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_MANAGER_H_
|
387
chromium_src/chrome/browser/printing/print_job_worker.cc
Normal file
387
chromium_src/chrome/browser/printing/print_job_worker.cc
Normal file
|
@ -0,0 +1,387 @@
|
|||
// Copyright (c) 2012 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/printing/print_job_worker.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/bind_helpers.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/values.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/chrome_notification_types.h"
|
||||
#include "chrome/browser/printing/print_job.h"
|
||||
#include "chrome/browser/printing/printing_ui_web_contents_observer.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/notification_service.h"
|
||||
#include "grit/generated_resources.h"
|
||||
#include "printing/print_job_constants.h"
|
||||
#include "printing/printed_document.h"
|
||||
#include "printing/printed_page.h"
|
||||
#include "printing/printing_utils.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper function to ensure |owner| is valid until at least |callback| returns.
|
||||
void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
|
||||
const base::Closure& callback) {
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace printing {
|
||||
|
||||
void NotificationCallback(PrintJobWorkerOwner* print_job,
|
||||
JobEventDetails::Type detail_type,
|
||||
PrintedDocument* document,
|
||||
PrintedPage* page) {
|
||||
JobEventDetails* details = new JobEventDetails(detail_type, document, page);
|
||||
content::NotificationService::current()->Notify(
|
||||
chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
// We know that is is a PrintJob object in this circumstance.
|
||||
content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
|
||||
content::Details<JobEventDetails>(details));
|
||||
}
|
||||
|
||||
PrintJobWorker::PrintJobWorker(PrintJobWorkerOwner* owner)
|
||||
: Thread("Printing_Worker"),
|
||||
owner_(owner),
|
||||
weak_factory_(this) {
|
||||
// The object is created in the IO thread.
|
||||
DCHECK_EQ(owner_->message_loop(), base::MessageLoop::current());
|
||||
|
||||
printing_context_.reset(PrintingContext::Create(
|
||||
g_browser_process->GetApplicationLocale()));
|
||||
}
|
||||
|
||||
PrintJobWorker::~PrintJobWorker() {
|
||||
// The object is normally deleted in the UI thread, but when the user
|
||||
// cancels printing or in the case of print preview, the worker is destroyed
|
||||
// on the I/O thread.
|
||||
DCHECK_EQ(owner_->message_loop(), base::MessageLoop::current());
|
||||
Stop();
|
||||
}
|
||||
|
||||
void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) {
|
||||
DCHECK(page_number_ == PageNumber::npos());
|
||||
owner_ = new_owner;
|
||||
}
|
||||
|
||||
void PrintJobWorker::SetPrintDestination(
|
||||
PrintDestinationInterface* destination) {
|
||||
destination_ = destination;
|
||||
}
|
||||
|
||||
void PrintJobWorker::GetSettings(
|
||||
bool ask_user_for_settings,
|
||||
scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
|
||||
int document_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type) {
|
||||
DCHECK_EQ(message_loop(), base::MessageLoop::current());
|
||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||
|
||||
// Recursive task processing is needed for the dialog in case it needs to be
|
||||
// destroyed by a task.
|
||||
// TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed
|
||||
// on the thread where the PrintDlgEx is called, and definitely both calls
|
||||
// should happen on the same thread. See http://crbug.com/73466
|
||||
// MessageLoop::current()->SetNestableTasksAllowed(true);
|
||||
printing_context_->set_margin_type(margin_type);
|
||||
|
||||
// When we delegate to a destination, we don't ask the user for settings.
|
||||
// TODO(mad): Ask the destination for settings.
|
||||
if (ask_user_for_settings && destination_.get() == NULL) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
|
||||
base::Bind(&PrintJobWorker::GetSettingsWithUI,
|
||||
base::Unretained(this),
|
||||
base::Passed(&web_contents_observer),
|
||||
document_page_count,
|
||||
has_selection)));
|
||||
} else {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
|
||||
base::Bind(&PrintJobWorker::UseDefaultSettings,
|
||||
base::Unretained(this))));
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJobWorker::SetSettings(
|
||||
const base::DictionaryValue* const new_settings) {
|
||||
DCHECK_EQ(message_loop(), base::MessageLoop::current());
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
|
||||
base::Bind(&PrintJobWorker::UpdatePrintSettings,
|
||||
base::Unretained(this), new_settings)));
|
||||
}
|
||||
|
||||
void PrintJobWorker::UpdatePrintSettings(
|
||||
const base::DictionaryValue* const new_settings) {
|
||||
// Create new PageRanges based on |new_settings|.
|
||||
PageRanges new_ranges;
|
||||
const base::ListValue* page_range_array;
|
||||
if (new_settings->GetList(kSettingPageRange, &page_range_array)) {
|
||||
for (size_t index = 0; index < page_range_array->GetSize(); ++index) {
|
||||
const base::DictionaryValue* dict;
|
||||
if (!page_range_array->GetDictionary(index, &dict))
|
||||
continue;
|
||||
|
||||
PageRange range;
|
||||
if (!dict->GetInteger(kSettingPageRangeFrom, &range.from) ||
|
||||
!dict->GetInteger(kSettingPageRangeTo, &range.to)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Page numbers are 1-based in the dictionary.
|
||||
// Page numbers are 0-based for the printing context.
|
||||
range.from--;
|
||||
range.to--;
|
||||
new_ranges.push_back(range);
|
||||
}
|
||||
}
|
||||
PrintingContext::Result result =
|
||||
printing_context_->UpdatePrintSettings(*new_settings, new_ranges);
|
||||
delete new_settings;
|
||||
GetSettingsDone(result);
|
||||
}
|
||||
|
||||
void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) {
|
||||
// Most PrintingContext functions may start a message loop and process
|
||||
// message recursively, so disable recursive task processing.
|
||||
// TODO(thestig): See above comment. SetNestableTasksAllowed(false) needs to
|
||||
// be called on the same thread as the previous call. See
|
||||
// http://crbug.com/73466
|
||||
// MessageLoop::current()->SetNestableTasksAllowed(false);
|
||||
|
||||
// We can't use OnFailure() here since owner_ may not support notifications.
|
||||
|
||||
// PrintJob will create the new PrintedDocument.
|
||||
owner_->message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&PrintJobWorkerOwner::GetSettingsDone,
|
||||
make_scoped_refptr(owner_), printing_context_->settings(),
|
||||
result));
|
||||
}
|
||||
|
||||
void PrintJobWorker::GetSettingsWithUI(
|
||||
scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
|
||||
int document_page_count,
|
||||
bool has_selection) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
gfx::NativeView parent_view = web_contents_observer->GetParentView();
|
||||
if (!parent_view) {
|
||||
GetSettingsWithUIDone(printing::PrintingContext::FAILED);
|
||||
return;
|
||||
}
|
||||
printing_context_->AskUserForSettings(
|
||||
parent_view, document_page_count, has_selection,
|
||||
base::Bind(&PrintJobWorker::GetSettingsWithUIDone,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) {
|
||||
message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
|
||||
base::Bind(&PrintJobWorker::GetSettingsDone,
|
||||
base::Unretained(this), result)));
|
||||
}
|
||||
|
||||
void PrintJobWorker::UseDefaultSettings() {
|
||||
PrintingContext::Result result = printing_context_->UseDefaultSettings();
|
||||
GetSettingsDone(result);
|
||||
}
|
||||
|
||||
void PrintJobWorker::StartPrinting(PrintedDocument* new_document) {
|
||||
DCHECK_EQ(message_loop(), base::MessageLoop::current());
|
||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||
DCHECK_EQ(document_, new_document);
|
||||
DCHECK(document_.get());
|
||||
|
||||
if (!document_.get() || page_number_ != PageNumber::npos() ||
|
||||
document_.get() != new_document) {
|
||||
return;
|
||||
}
|
||||
|
||||
base::string16 document_name =
|
||||
printing::SimplifyDocumentTitle(document_->name());
|
||||
if (document_name.empty()) {
|
||||
// document_name = printing::SimplifyDocumentTitle(
|
||||
// l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE));
|
||||
}
|
||||
PrintingContext::Result result =
|
||||
printing_context_->NewDocument(document_name);
|
||||
if (result != PrintingContext::OK) {
|
||||
OnFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to print already cached data. It may already have been generated for
|
||||
// the print preview.
|
||||
OnNewPage();
|
||||
// Don't touch this anymore since the instance could be destroyed. It happens
|
||||
// if all the pages are printed a one sweep and the client doesn't have a
|
||||
// handle to us anymore. There's a timing issue involved between the worker
|
||||
// thread and the UI thread. Take no chance.
|
||||
}
|
||||
|
||||
void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) {
|
||||
DCHECK_EQ(message_loop(), base::MessageLoop::current());
|
||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||
|
||||
if (page_number_ != PageNumber::npos())
|
||||
return;
|
||||
|
||||
document_ = new_document;
|
||||
}
|
||||
|
||||
void PrintJobWorker::OnNewPage() {
|
||||
if (!document_.get()) // Spurious message.
|
||||
return;
|
||||
|
||||
// message_loop() could return NULL when the print job is cancelled.
|
||||
DCHECK_EQ(message_loop(), base::MessageLoop::current());
|
||||
|
||||
if (page_number_ == PageNumber::npos()) {
|
||||
// Find first page to print.
|
||||
int page_count = document_->page_count();
|
||||
if (!page_count) {
|
||||
// We still don't know how many pages the document contains. We can't
|
||||
// start to print the document yet since the header/footer may refer to
|
||||
// the document's page count.
|
||||
return;
|
||||
}
|
||||
// We have enough information to initialize page_number_.
|
||||
page_number_.Init(document_->settings(), page_count);
|
||||
if (destination_.get() != NULL)
|
||||
destination_->SetPageCount(page_count);
|
||||
}
|
||||
DCHECK_NE(page_number_, PageNumber::npos());
|
||||
|
||||
while (true) {
|
||||
// Is the page available?
|
||||
scoped_refptr<PrintedPage> page;
|
||||
if (!document_->GetPage(page_number_.ToInt(), &page)) {
|
||||
// We need to wait for the page to be available.
|
||||
base::MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&PrintJobWorker::OnNewPage, weak_factory_.GetWeakPtr()),
|
||||
base::TimeDelta::FromMilliseconds(500));
|
||||
break;
|
||||
}
|
||||
// The page is there, print it.
|
||||
SpoolPage(page.get());
|
||||
++page_number_;
|
||||
if (page_number_ == PageNumber::npos()) {
|
||||
OnDocumentDone();
|
||||
// Don't touch this anymore since the instance could be destroyed.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJobWorker::Cancel() {
|
||||
// This is the only function that can be called from any thread.
|
||||
printing_context_->Cancel();
|
||||
// Cannot touch any member variable since we don't know in which thread
|
||||
// context we run.
|
||||
}
|
||||
|
||||
void PrintJobWorker::OnDocumentDone() {
|
||||
DCHECK_EQ(message_loop(), base::MessageLoop::current());
|
||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||
DCHECK(document_.get());
|
||||
|
||||
if (printing_context_->DocumentDone() != PrintingContext::OK) {
|
||||
OnFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
owner_->message_loop()->PostTask(
|
||||
FROM_HERE, base::Bind(NotificationCallback, make_scoped_refptr(owner_),
|
||||
JobEventDetails::DOC_DONE, document_,
|
||||
scoped_refptr<PrintedPage>()));
|
||||
|
||||
// Makes sure the variables are reinitialized.
|
||||
document_ = NULL;
|
||||
}
|
||||
|
||||
void PrintJobWorker::SpoolPage(PrintedPage* page) {
|
||||
DCHECK_EQ(message_loop(), base::MessageLoop::current());
|
||||
DCHECK_NE(page_number_, PageNumber::npos());
|
||||
|
||||
// Signal everyone that the page is about to be printed.
|
||||
owner_->message_loop()->PostTask(
|
||||
FROM_HERE, base::Bind(NotificationCallback, make_scoped_refptr(owner_),
|
||||
JobEventDetails::NEW_PAGE, document_,
|
||||
make_scoped_refptr(page)));
|
||||
|
||||
// Preprocess.
|
||||
if (printing_context_->NewPage() != PrintingContext::OK) {
|
||||
OnFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
if (destination_.get() != NULL) {
|
||||
std::vector<uint8> metabytes(page->metafile()->GetDataSize());
|
||||
bool success = page->metafile()->GetData(
|
||||
reinterpret_cast<void*>(&metabytes[0]), metabytes.size());
|
||||
DCHECK(success) << "Failed to get metafile data.";
|
||||
destination_->SetPageContent(
|
||||
page->page_number(),
|
||||
reinterpret_cast<void*>(&metabytes[0]),
|
||||
metabytes.size());
|
||||
return;
|
||||
}
|
||||
|
||||
// Actual printing.
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
document_->RenderPrintedPage(*page, printing_context_->context());
|
||||
#elif defined(OS_POSIX)
|
||||
document_->RenderPrintedPage(*page, printing_context_.get());
|
||||
#endif
|
||||
|
||||
// Postprocess.
|
||||
if (printing_context_->PageDone() != PrintingContext::OK) {
|
||||
OnFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
// Signal everyone that the page is printed.
|
||||
owner_->message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(NotificationCallback, make_scoped_refptr(owner_),
|
||||
JobEventDetails::PAGE_DONE, document_,
|
||||
make_scoped_refptr(page)));
|
||||
}
|
||||
|
||||
void PrintJobWorker::OnFailure() {
|
||||
DCHECK_EQ(message_loop(), base::MessageLoop::current());
|
||||
|
||||
// We may loose our last reference by broadcasting the FAILED event.
|
||||
scoped_refptr<PrintJobWorkerOwner> handle(owner_);
|
||||
|
||||
owner_->message_loop()->PostTask(
|
||||
FROM_HERE, base::Bind(NotificationCallback, make_scoped_refptr(owner_),
|
||||
JobEventDetails::FAILED, document_,
|
||||
scoped_refptr<PrintedPage>()));
|
||||
Cancel();
|
||||
|
||||
// Makes sure the variables are reinitialized.
|
||||
document_ = NULL;
|
||||
page_number_ = PageNumber::npos();
|
||||
}
|
||||
|
||||
} // namespace printing
|
145
chromium_src/chrome/browser/printing/print_job_worker.h
Normal file
145
chromium_src/chrome/browser/printing/print_job_worker.h
Normal file
|
@ -0,0 +1,145 @@
|
|||
// Copyright (c) 2012 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_PRINTING_PRINT_JOB_WORKER_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_H_
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "printing/page_number.h"
|
||||
#include "printing/print_destination_interface.h"
|
||||
#include "printing/printing_context.h"
|
||||
#include "printing/print_job_constants.h"
|
||||
|
||||
class PrintingUIWebContentsObserver;
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace printing {
|
||||
|
||||
class PrintedDocument;
|
||||
class PrintedPage;
|
||||
class PrintJob;
|
||||
class PrintJobWorkerOwner;
|
||||
|
||||
// Worker thread code. It manages the PrintingContext, which can be blocking
|
||||
// and/or run a message loop. This is the object that generates most
|
||||
// NOTIFY_PRINT_JOB_EVENT notifications, but they are generated through a
|
||||
// NotificationTask task to be executed from the right thread, the UI thread.
|
||||
// PrintJob always outlives its worker instance.
|
||||
class PrintJobWorker : public base::Thread {
|
||||
public:
|
||||
explicit PrintJobWorker(PrintJobWorkerOwner* owner);
|
||||
virtual ~PrintJobWorker();
|
||||
|
||||
void SetNewOwner(PrintJobWorkerOwner* new_owner);
|
||||
|
||||
// Set a destination for print.
|
||||
// This supercedes the document's rendering destination.
|
||||
void SetPrintDestination(PrintDestinationInterface* destination);
|
||||
|
||||
// Initializes the print settings. If |ask_user_for_settings| is true, a
|
||||
// Print... dialog box will be shown to ask the user his preference.
|
||||
void GetSettings(
|
||||
bool ask_user_for_settings,
|
||||
scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
|
||||
int document_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type);
|
||||
|
||||
// Set the new print settings. This function takes ownership of
|
||||
// |new_settings|.
|
||||
void SetSettings(const base::DictionaryValue* const new_settings);
|
||||
|
||||
// Starts the printing loop. Every pages are printed as soon as the data is
|
||||
// available. Makes sure the new_document is the right one.
|
||||
void StartPrinting(PrintedDocument* new_document);
|
||||
|
||||
// Updates the printed document.
|
||||
void OnDocumentChanged(PrintedDocument* new_document);
|
||||
|
||||
// Dequeues waiting pages. Called when PrintJob receives a
|
||||
// NOTIFY_PRINTED_DOCUMENT_UPDATED notification. It's time to look again if
|
||||
// the next page can be printed.
|
||||
void OnNewPage();
|
||||
|
||||
// This is the only function that can be called in a thread.
|
||||
void Cancel();
|
||||
|
||||
protected:
|
||||
// Retrieves the context for testing only.
|
||||
PrintingContext* printing_context() { return printing_context_.get(); }
|
||||
|
||||
private:
|
||||
// The shared NotificationService service can only be accessed from the UI
|
||||
// thread, so this class encloses the necessary information to send the
|
||||
// notification from the right thread. Most NOTIFY_PRINT_JOB_EVENT
|
||||
// notifications are sent this way, except USER_INIT_DONE, USER_INIT_CANCELED
|
||||
// and DEFAULT_INIT_DONE. These three are sent through PrintJob::InitDone().
|
||||
class NotificationTask;
|
||||
|
||||
// Renders a page in the printer.
|
||||
void SpoolPage(PrintedPage* page);
|
||||
|
||||
// Closes the job since spooling is done.
|
||||
void OnDocumentDone();
|
||||
|
||||
// Discards the current document, the current page and cancels the printing
|
||||
// context.
|
||||
void OnFailure();
|
||||
|
||||
// Asks the user for print settings. Must be called on the UI thread.
|
||||
// Required on Mac and Linux. Windows can display UI from non-main threads,
|
||||
// but sticks with this for consistency.
|
||||
void GetSettingsWithUI(
|
||||
scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
|
||||
int document_page_count,
|
||||
bool has_selection);
|
||||
|
||||
// The callback used by PrintingContext::GetSettingsWithUI() to notify this
|
||||
// object that the print settings are set. This is needed in order to bounce
|
||||
// back into the IO thread for GetSettingsDone().
|
||||
void GetSettingsWithUIDone(PrintingContext::Result result);
|
||||
|
||||
// Called on the UI thread to update the print settings. This function takes
|
||||
// the ownership of |new_settings|.
|
||||
void UpdatePrintSettings(const base::DictionaryValue* const new_settings);
|
||||
|
||||
// Reports settings back to owner_.
|
||||
void GetSettingsDone(PrintingContext::Result result);
|
||||
|
||||
// Use the default settings. When using GTK+ or Mac, this can still end up
|
||||
// displaying a dialog. So this needs to happen from the UI thread on these
|
||||
// systems.
|
||||
void UseDefaultSettings();
|
||||
|
||||
// Information about the printer setting.
|
||||
scoped_ptr<PrintingContext> printing_context_;
|
||||
|
||||
// The printed document. Only has read-only access.
|
||||
scoped_refptr<PrintedDocument> document_;
|
||||
|
||||
// The print destination, may be NULL.
|
||||
scoped_refptr<PrintDestinationInterface> destination_;
|
||||
|
||||
// The print job owning this worker thread. It is guaranteed to outlive this
|
||||
// object.
|
||||
PrintJobWorkerOwner* owner_;
|
||||
|
||||
// Current page number to print.
|
||||
PageNumber page_number_;
|
||||
|
||||
// Used to generate a WeakPtr for callbacks.
|
||||
base::WeakPtrFactory<PrintJobWorker> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintJobWorker);
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_H_
|
|
@ -0,0 +1,50 @@
|
|||
// 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_PRINTING_PRINT_JOB_WORKER_OWNER_H__
|
||||
#define CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "printing/printing_context.h"
|
||||
|
||||
namespace base {
|
||||
class MessageLoop;
|
||||
}
|
||||
|
||||
|
||||
namespace printing {
|
||||
|
||||
class PrintJobWorker;
|
||||
class PrintSettings;
|
||||
|
||||
class PrintJobWorkerOwner
|
||||
: public base::RefCountedThreadSafe<PrintJobWorkerOwner> {
|
||||
public:
|
||||
// Finishes the initialization began by PrintJobWorker::GetSettings().
|
||||
// Creates a new PrintedDocument if necessary. Solely meant to be called by
|
||||
// PrintJobWorker.
|
||||
virtual void GetSettingsDone(const PrintSettings& new_settings,
|
||||
PrintingContext::Result result) = 0;
|
||||
|
||||
// Detach the PrintJobWorker associated to this object.
|
||||
virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) = 0;
|
||||
|
||||
// Retrieves the message loop that is expected to process GetSettingsDone.
|
||||
virtual base::MessageLoop* message_loop() = 0;
|
||||
|
||||
// Access the current settings.
|
||||
virtual const PrintSettings& settings() const = 0;
|
||||
|
||||
// Cookie uniquely identifying the PrintedDocument and/or loaded settings.
|
||||
virtual int cookie() const = 0;
|
||||
|
||||
protected:
|
||||
friend class base::RefCountedThreadSafe<PrintJobWorkerOwner>;
|
||||
|
||||
virtual ~PrintJobWorkerOwner() {}
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
|
509
chromium_src/chrome/browser/printing/print_view_manager_base.cc
Normal file
509
chromium_src/chrome/browser/printing/print_view_manager_base.cc
Normal file
|
@ -0,0 +1,509 @@
|
|||
// Copyright 2013 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/printing/print_view_manager_base.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/chrome_notification_types.h"
|
||||
#include "chrome/browser/printing/print_job.h"
|
||||
#include "chrome/browser/printing/print_job_manager.h"
|
||||
#include "chrome/browser/printing/printer_query.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/ui/simple_message_box.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/notification_details.h"
|
||||
#include "content/public/browser/notification_service.h"
|
||||
#include "content/public/browser/notification_source.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "grit/generated_resources.h"
|
||||
#include "printing/metafile_impl.h"
|
||||
#include "printing/printed_document.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
using base::TimeDelta;
|
||||
using content::BrowserThread;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Limits memory usage by raster to 64 MiB.
|
||||
const int kMaxRasterSizeInPixels = 16*1024*1024;
|
||||
#endif
|
||||
|
||||
namespace printing {
|
||||
|
||||
PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
number_pages_(0),
|
||||
printing_succeeded_(false),
|
||||
inside_inner_message_loop_(false),
|
||||
cookie_(0),
|
||||
queue_(g_browser_process->print_job_manager()->queue()) {
|
||||
DCHECK(queue_);
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||
expecting_first_page_ = true;
|
||||
#endif
|
||||
printing_enabled_ = true;
|
||||
}
|
||||
|
||||
PrintViewManagerBase::~PrintViewManagerBase() {
|
||||
ReleasePrinterQuery();
|
||||
DisconnectFromCurrentPrintJob();
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::PrintNow(bool silent, bool print_background) {
|
||||
return PrintNowInternal(new PrintMsg_PrintPages(
|
||||
routing_id(), silent, print_background));
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::NavigationStopped() {
|
||||
// Cancel the current job, wait for the worker to finish.
|
||||
TerminatePrintJob(true);
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::RenderProcessGone(base::TerminationStatus status) {
|
||||
ReleasePrinterQuery();
|
||||
|
||||
if (!print_job_.get())
|
||||
return;
|
||||
|
||||
scoped_refptr<PrintedDocument> document(print_job_->document());
|
||||
if (document.get()) {
|
||||
// If IsComplete() returns false, the document isn't completely rendered.
|
||||
// Since our renderer is gone, there's nothing to do, cancel it. Otherwise,
|
||||
// the print job may finish without problem.
|
||||
TerminatePrintJob(!document->IsComplete());
|
||||
}
|
||||
}
|
||||
|
||||
base::string16 PrintViewManagerBase::RenderSourceName() {
|
||||
base::string16 name(web_contents()->GetTitle());
|
||||
return name;
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie,
|
||||
int number_pages) {
|
||||
DCHECK_GT(cookie, 0);
|
||||
DCHECK_GT(number_pages, 0);
|
||||
number_pages_ = number_pages;
|
||||
OpportunisticallyCreatePrintJob(cookie);
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnDidGetDocumentCookie(int cookie) {
|
||||
cookie_ = cookie;
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnDidPrintPage(
|
||||
const PrintHostMsg_DidPrintPage_Params& params) {
|
||||
if (!OpportunisticallyCreatePrintJob(params.document_cookie))
|
||||
return;
|
||||
|
||||
PrintedDocument* document = print_job_->document();
|
||||
if (!document || params.document_cookie != document->cookie()) {
|
||||
// Out of sync. It may happen since we are completely asynchronous. Old
|
||||
// spurious messages can be received if one of the processes is overloaded.
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
const bool metafile_must_be_valid = true;
|
||||
#elif defined(OS_POSIX)
|
||||
const bool metafile_must_be_valid = expecting_first_page_;
|
||||
expecting_first_page_ = false;
|
||||
#endif
|
||||
|
||||
base::SharedMemory shared_buf(params.metafile_data_handle, true);
|
||||
if (metafile_must_be_valid) {
|
||||
if (!shared_buf.Map(params.data_size)) {
|
||||
NOTREACHED() << "couldn't map";
|
||||
web_contents()->Stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scoped_ptr<NativeMetafile> metafile(new NativeMetafile);
|
||||
if (metafile_must_be_valid) {
|
||||
if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) {
|
||||
NOTREACHED() << "Invalid metafile header";
|
||||
web_contents()->Stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool big_emf = (params.data_size && params.data_size >= kMetafileMaxSize);
|
||||
int raster_size = std::min(params.page_size.GetArea(),
|
||||
kMaxRasterSizeInPixels);
|
||||
if (big_emf) {
|
||||
scoped_ptr<NativeMetafile> raster_metafile(
|
||||
metafile->RasterizeMetafile(raster_size));
|
||||
if (raster_metafile.get()) {
|
||||
metafile.swap(raster_metafile);
|
||||
} else if (big_emf) {
|
||||
// Don't fall back to emf here.
|
||||
NOTREACHED() << "size:" << params.data_size;
|
||||
TerminatePrintJob(true);
|
||||
web_contents()->Stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Update the rendered document. It will send notifications to the listener.
|
||||
document->SetPage(params.page_number,
|
||||
metafile.release(),
|
||||
params.actual_shrink,
|
||||
params.page_size,
|
||||
params.content_area);
|
||||
|
||||
ShouldQuitFromInnerMessageLoop();
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnPrintingFailed(int cookie) {
|
||||
if (cookie != cookie_) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
ReleasePrinterQuery();
|
||||
|
||||
content::NotificationService::current()->Notify(
|
||||
chrome::NOTIFICATION_PRINT_JOB_RELEASED,
|
||||
content::Source<content::WebContents>(web_contents()),
|
||||
content::NotificationService::NoDetails());
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnShowInvalidPrinterSettingsError() {
|
||||
LOG(ERROR) << "Invalid printer settings";
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::DidStartLoading(
|
||||
content::RenderViewHost* render_view_host) {
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message)
|
||||
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount,
|
||||
OnDidGetPrintedPagesCount)
|
||||
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDocumentCookie,
|
||||
OnDidGetDocumentCookie)
|
||||
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
|
||||
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed)
|
||||
IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError,
|
||||
OnShowInvalidPrinterSettingsError);
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::Observe(
|
||||
int type,
|
||||
const content::NotificationSource& source,
|
||||
const content::NotificationDetails& details) {
|
||||
switch (type) {
|
||||
case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
|
||||
OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnNotifyPrintJobEvent(
|
||||
const JobEventDetails& event_details) {
|
||||
switch (event_details.type()) {
|
||||
case JobEventDetails::FAILED: {
|
||||
TerminatePrintJob(true);
|
||||
|
||||
content::NotificationService::current()->Notify(
|
||||
chrome::NOTIFICATION_PRINT_JOB_RELEASED,
|
||||
content::Source<content::WebContents>(web_contents()),
|
||||
content::NotificationService::NoDetails());
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::USER_INIT_DONE:
|
||||
case JobEventDetails::DEFAULT_INIT_DONE:
|
||||
case JobEventDetails::USER_INIT_CANCELED: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::ALL_PAGES_REQUESTED: {
|
||||
ShouldQuitFromInnerMessageLoop();
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::NEW_DOC:
|
||||
case JobEventDetails::NEW_PAGE:
|
||||
case JobEventDetails::PAGE_DONE:
|
||||
case JobEventDetails::DOC_DONE: {
|
||||
// Don't care about the actual printing process.
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::JOB_DONE: {
|
||||
// Printing is done, we don't need it anymore.
|
||||
// print_job_->is_job_pending() may still be true, depending on the order
|
||||
// of object registration.
|
||||
printing_succeeded_ = true;
|
||||
ReleasePrintJob();
|
||||
|
||||
content::NotificationService::current()->Notify(
|
||||
chrome::NOTIFICATION_PRINT_JOB_RELEASED,
|
||||
content::Source<content::WebContents>(web_contents()),
|
||||
content::NotificationService::NoDetails());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::RenderAllMissingPagesNow() {
|
||||
if (!print_job_.get() || !print_job_->is_job_pending())
|
||||
return false;
|
||||
|
||||
// We can't print if there is no renderer.
|
||||
if (!web_contents() ||
|
||||
!web_contents()->GetRenderViewHost() ||
|
||||
!web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is the document already complete?
|
||||
if (print_job_->document() && print_job_->document()->IsComplete()) {
|
||||
printing_succeeded_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// WebContents is either dying or a second consecutive request to print
|
||||
// happened before the first had time to finish. We need to render all the
|
||||
// pages in an hurry if a print_job_ is still pending. No need to wait for it
|
||||
// to actually spool the pages, only to have the renderer generate them. Run
|
||||
// a message loop until we get our signal that the print job is satisfied.
|
||||
// PrintJob will send a ALL_PAGES_REQUESTED after having received all the
|
||||
// pages it needs. MessageLoop::current()->Quit() will be called as soon as
|
||||
// print_job_->document()->IsComplete() is true on either ALL_PAGES_REQUESTED
|
||||
// or in DidPrintPage(). The check is done in
|
||||
// ShouldQuitFromInnerMessageLoop().
|
||||
// BLOCKS until all the pages are received. (Need to enable recursive task)
|
||||
if (!RunInnerMessageLoop()) {
|
||||
// This function is always called from DisconnectFromCurrentPrintJob() so we
|
||||
// know that the job will be stopped/canceled in any case.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::ShouldQuitFromInnerMessageLoop() {
|
||||
// Look at the reason.
|
||||
DCHECK(print_job_->document());
|
||||
if (print_job_->document() &&
|
||||
print_job_->document()->IsComplete() &&
|
||||
inside_inner_message_loop_) {
|
||||
// We are in a message loop created by RenderAllMissingPagesNow. Quit from
|
||||
// it.
|
||||
base::MessageLoop::current()->Quit();
|
||||
inside_inner_message_loop_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::CreateNewPrintJob(PrintJobWorkerOwner* job) {
|
||||
DCHECK(!inside_inner_message_loop_);
|
||||
|
||||
// Disconnect the current print_job_.
|
||||
DisconnectFromCurrentPrintJob();
|
||||
|
||||
// We can't print if there is no renderer.
|
||||
if (!web_contents()->GetRenderViewHost() ||
|
||||
!web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ask the renderer to generate the print preview, create the print preview
|
||||
// view and switch to it, initialize the printer and show the print dialog.
|
||||
DCHECK(!print_job_.get());
|
||||
DCHECK(job);
|
||||
if (!job)
|
||||
return false;
|
||||
|
||||
print_job_ = new PrintJob();
|
||||
print_job_->Initialize(job, this, number_pages_);
|
||||
registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
content::Source<PrintJob>(print_job_.get()));
|
||||
printing_succeeded_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::DisconnectFromCurrentPrintJob() {
|
||||
// Make sure all the necessary rendered page are done. Don't bother with the
|
||||
// return value.
|
||||
bool result = RenderAllMissingPagesNow();
|
||||
|
||||
// Verify that assertion.
|
||||
if (print_job_.get() &&
|
||||
print_job_->document() &&
|
||||
!print_job_->document()->IsComplete()) {
|
||||
DCHECK(!result);
|
||||
// That failed.
|
||||
TerminatePrintJob(true);
|
||||
} else {
|
||||
// DO NOT wait for the job to finish.
|
||||
ReleasePrintJob();
|
||||
}
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||
expecting_first_page_ = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::PrintingDone(bool success) {
|
||||
if (!print_job_.get())
|
||||
return;
|
||||
Send(new PrintMsg_PrintingDone(routing_id(), success));
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::TerminatePrintJob(bool cancel) {
|
||||
if (!print_job_.get())
|
||||
return;
|
||||
|
||||
if (cancel) {
|
||||
// We don't need the metafile data anymore because the printing is canceled.
|
||||
print_job_->Cancel();
|
||||
inside_inner_message_loop_ = false;
|
||||
} else {
|
||||
DCHECK(!inside_inner_message_loop_);
|
||||
DCHECK(!print_job_->document() || print_job_->document()->IsComplete());
|
||||
|
||||
// WebContents is either dying or navigating elsewhere. We need to render
|
||||
// all the pages in an hurry if a print job is still pending. This does the
|
||||
// trick since it runs a blocking message loop:
|
||||
print_job_->Stop();
|
||||
}
|
||||
ReleasePrintJob();
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::ReleasePrintJob() {
|
||||
if (!print_job_.get())
|
||||
return;
|
||||
|
||||
PrintingDone(printing_succeeded_);
|
||||
|
||||
registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||
content::Source<PrintJob>(print_job_.get()));
|
||||
print_job_->DisconnectSource();
|
||||
// Don't close the worker thread.
|
||||
print_job_ = NULL;
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
// This value may actually be too low:
|
||||
//
|
||||
// - If we're looping because of printer settings initialization, the premise
|
||||
// here is that some poor users have their print server away on a VPN over a
|
||||
// slow connection. In this situation, the simple fact of opening the printer
|
||||
// can be dead slow. On the other side, we don't want to die infinitely for a
|
||||
// real network error. Give the printer 60 seconds to comply.
|
||||
//
|
||||
// - If we're looping because of renderer page generation, the renderer could
|
||||
// be CPU bound, the page overly complex/large or the system just
|
||||
// memory-bound.
|
||||
static const int kPrinterSettingsTimeout = 60000;
|
||||
base::OneShotTimer<base::MessageLoop> quit_timer;
|
||||
quit_timer.Start(FROM_HERE,
|
||||
TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
|
||||
base::MessageLoop::current(), &base::MessageLoop::Quit);
|
||||
|
||||
inside_inner_message_loop_ = true;
|
||||
|
||||
// Need to enable recursive task.
|
||||
{
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||
base::MessageLoop::current());
|
||||
base::MessageLoop::current()->Run();
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
if (inside_inner_message_loop_) {
|
||||
// Ok we timed out. That's sad.
|
||||
inside_inner_message_loop_ = false;
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
if (print_job_.get())
|
||||
return true;
|
||||
|
||||
if (!cookie) {
|
||||
// Out of sync. It may happens since we are completely asynchronous. Old
|
||||
// spurious message can happen if one of the processes is overloaded.
|
||||
return false;
|
||||
}
|
||||
|
||||
// The job was initiated by a script. Time to get the corresponding worker
|
||||
// thread.
|
||||
scoped_refptr<PrinterQuery> queued_query = queue_->PopPrinterQuery(cookie);
|
||||
if (!queued_query) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateNewPrintJob(queued_query)) {
|
||||
// Don't kill anything.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Settings are already loaded. Go ahead. This will set
|
||||
// print_job_->is_job_pending() to true.
|
||||
print_job_->StartPrinting();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::PrintNowInternal(IPC::Message* message) {
|
||||
// Don't print / print preview interstitials.
|
||||
if (web_contents()->ShowingInterstitialPage()) {
|
||||
delete message;
|
||||
return false;
|
||||
}
|
||||
return Send(message);
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::ReleasePrinterQuery() {
|
||||
if (!cookie_)
|
||||
return;
|
||||
|
||||
int cookie = cookie_;
|
||||
cookie_ = 0;
|
||||
queue_->SetDestination(NULL);
|
||||
|
||||
|
||||
printing::PrintJobManager* print_job_manager =
|
||||
g_browser_process->print_job_manager();
|
||||
// May be NULL in tests.
|
||||
if (!print_job_manager)
|
||||
return;
|
||||
|
||||
scoped_refptr<printing::PrinterQuery> printer_query;
|
||||
printer_query = queue_->PopPrinterQuery(cookie);
|
||||
if (!printer_query)
|
||||
return;
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&PrinterQuery::StopWorker, printer_query.get()));
|
||||
}
|
||||
|
||||
} // namespace printing
|
164
chromium_src/chrome/browser/printing/print_view_manager_base.h
Normal file
164
chromium_src/chrome/browser/printing/print_view_manager_base.h
Normal file
|
@ -0,0 +1,164 @@
|
|||
// Copyright 2013 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_PRINTING_PRINT_VIEW_MANAGER_BASE_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/prefs/pref_member.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "content/public/browser/notification_observer.h"
|
||||
#include "content/public/browser/notification_registrar.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "printing/printed_pages_source.h"
|
||||
|
||||
struct PrintHostMsg_DidPrintPage_Params;
|
||||
|
||||
namespace content {
|
||||
class RenderViewHost;
|
||||
}
|
||||
|
||||
namespace printing {
|
||||
|
||||
class JobEventDetails;
|
||||
class PrintJob;
|
||||
class PrintJobWorkerOwner;
|
||||
class PrintQueriesQueue;
|
||||
|
||||
// Base class for managing the print commands for a WebContents.
|
||||
class PrintViewManagerBase : public content::NotificationObserver,
|
||||
public PrintedPagesSource,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
virtual ~PrintViewManagerBase();
|
||||
|
||||
// Prints the current document immediately. Since the rendering is
|
||||
// asynchronous, the actual printing will not be completed on the return of
|
||||
// this function. Returns false if printing is impossible at the moment.
|
||||
virtual bool PrintNow(bool silent, bool print_background);
|
||||
|
||||
// PrintedPagesSource implementation.
|
||||
virtual base::string16 RenderSourceName() OVERRIDE;
|
||||
|
||||
protected:
|
||||
explicit PrintViewManagerBase(content::WebContents* web_contents);
|
||||
|
||||
// Helper method for Print*Now().
|
||||
bool PrintNowInternal(IPC::Message* message);
|
||||
|
||||
// Terminates or cancels the print job if one was pending.
|
||||
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
|
||||
|
||||
// content::WebContentsObserver implementation.
|
||||
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||
|
||||
// IPC Message handlers.
|
||||
virtual void OnPrintingFailed(int cookie);
|
||||
|
||||
private:
|
||||
// content::NotificationObserver implementation.
|
||||
virtual void Observe(int type,
|
||||
const content::NotificationSource& source,
|
||||
const content::NotificationDetails& details) OVERRIDE;
|
||||
|
||||
// content::WebContentsObserver implementation.
|
||||
virtual void DidStartLoading(
|
||||
content::RenderViewHost* render_view_host) OVERRIDE;
|
||||
|
||||
// Cancels the print job.
|
||||
virtual void NavigationStopped() OVERRIDE;
|
||||
|
||||
// IPC Message handlers.
|
||||
void OnDidGetPrintedPagesCount(int cookie, int number_pages);
|
||||
void OnDidGetDocumentCookie(int cookie);
|
||||
void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params);
|
||||
void OnShowInvalidPrinterSettingsError();
|
||||
|
||||
// Processes a NOTIFY_PRINT_JOB_EVENT notification.
|
||||
void OnNotifyPrintJobEvent(const JobEventDetails& event_details);
|
||||
|
||||
// Requests the RenderView to render all the missing pages for the print job.
|
||||
// No-op if no print job is pending. Returns true if at least one page has
|
||||
// been requested to the renderer.
|
||||
bool RenderAllMissingPagesNow();
|
||||
|
||||
// Quits the current message loop if these conditions hold true: a document is
|
||||
// loaded and is complete and waiting_for_pages_to_be_rendered_ is true. This
|
||||
// function is called in DidPrintPage() or on ALL_PAGES_REQUESTED
|
||||
// notification. The inner message loop is created was created by
|
||||
// RenderAllMissingPagesNow().
|
||||
void ShouldQuitFromInnerMessageLoop();
|
||||
|
||||
// Creates a new empty print job. It has no settings loaded. If there is
|
||||
// currently a print job, safely disconnect from it. Returns false if it is
|
||||
// impossible to safely disconnect from the current print job or it is
|
||||
// impossible to create a new print job.
|
||||
bool CreateNewPrintJob(PrintJobWorkerOwner* job);
|
||||
|
||||
// Makes sure the current print_job_ has all its data before continuing, and
|
||||
// disconnect from it.
|
||||
void DisconnectFromCurrentPrintJob();
|
||||
|
||||
// Notify that the printing is done.
|
||||
void PrintingDone(bool success);
|
||||
|
||||
// Terminates the print job. No-op if no print job has been created. If
|
||||
// |cancel| is true, cancel it instead of waiting for the job to finish. Will
|
||||
// call ReleasePrintJob().
|
||||
void TerminatePrintJob(bool cancel);
|
||||
|
||||
// Releases print_job_. Correctly deregisters from notifications. No-op if
|
||||
// no print job has been created.
|
||||
void ReleasePrintJob();
|
||||
|
||||
// Runs an inner message loop. It will set inside_inner_message_loop_ to true
|
||||
// while the blocking inner message loop is running. This is useful in cases
|
||||
// where the RenderView is about to be destroyed while a printing job isn't
|
||||
// finished.
|
||||
bool RunInnerMessageLoop();
|
||||
|
||||
// In the case of Scripted Printing, where the renderer is controlling the
|
||||
// control flow, print_job_ is initialized whenever possible. No-op is
|
||||
// print_job_ is initialized.
|
||||
bool OpportunisticallyCreatePrintJob(int cookie);
|
||||
|
||||
// Release the PrinterQuery associated with our |cookie_|.
|
||||
void ReleasePrinterQuery();
|
||||
|
||||
content::NotificationRegistrar registrar_;
|
||||
|
||||
// Manages the low-level talk to the printer.
|
||||
scoped_refptr<PrintJob> print_job_;
|
||||
|
||||
// Number of pages to print in the print job.
|
||||
int number_pages_;
|
||||
|
||||
// Indication of success of the print job.
|
||||
bool printing_succeeded_;
|
||||
|
||||
// Running an inner message loop inside RenderAllMissingPagesNow(). This means
|
||||
// we are _blocking_ until all the necessary pages have been rendered or the
|
||||
// print settings are being loaded.
|
||||
bool inside_inner_message_loop_;
|
||||
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||
// Set to true when OnDidPrintPage() should be expecting the first page.
|
||||
bool expecting_first_page_;
|
||||
#endif
|
||||
|
||||
// The document cookie of the current PrinterQuery.
|
||||
int cookie_;
|
||||
|
||||
// Whether printing is enabled.
|
||||
bool printing_enabled_;
|
||||
|
||||
scoped_refptr<printing::PrintQueriesQueue> queue_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBase);
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2013 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/printing/print_view_manager_basic.h"
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
#include "base/file_descriptor_posix.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "printing/printing_context_android.h"
|
||||
#endif
|
||||
|
||||
DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintViewManagerBasic);
|
||||
|
||||
namespace printing {
|
||||
|
||||
PrintViewManagerBasic::PrintViewManagerBasic(content::WebContents* web_contents)
|
||||
: PrintViewManagerBase(web_contents) {
|
||||
}
|
||||
|
||||
PrintViewManagerBasic::~PrintViewManagerBasic() {
|
||||
}
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
void PrintViewManagerBasic::RenderProcessGone(base::TerminationStatus status) {
|
||||
PrintingContextAndroid::PdfWritingDone(file_descriptor_.fd, false);
|
||||
file_descriptor_ = base::FileDescriptor(-1, false);
|
||||
PrintViewManagerBase::RenderProcessGone(status);
|
||||
}
|
||||
|
||||
void PrintViewManagerBasic::OnPrintingFailed(int cookie) {
|
||||
PrintingContextAndroid::PdfWritingDone(file_descriptor_.fd, false);
|
||||
file_descriptor_ = base::FileDescriptor(-1, false);
|
||||
PrintViewManagerBase::OnPrintingFailed(cookie);
|
||||
}
|
||||
|
||||
bool PrintViewManagerBasic::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBasic, message)
|
||||
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
|
||||
return handled ? true : PrintViewManagerBase::OnMessageReceived(message);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace printing
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2013 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_PRINTING_PRINT_VIEW_MANAGER_BASIC_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASIC_H_
|
||||
|
||||
#include "chrome/browser/printing/print_view_manager_base.h"
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
#include "base/file_descriptor_posix.h"
|
||||
#endif
|
||||
|
||||
namespace printing {
|
||||
|
||||
// Manages the print commands for a WebContents - basic version.
|
||||
class PrintViewManagerBasic
|
||||
: public PrintViewManagerBase,
|
||||
public content::WebContentsUserData<PrintViewManagerBasic> {
|
||||
public:
|
||||
virtual ~PrintViewManagerBasic();
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
// Sets the file descriptor into which the PDF will be written.
|
||||
void set_file_descriptor(const base::FileDescriptor& file_descriptor) {
|
||||
file_descriptor_ = file_descriptor;
|
||||
}
|
||||
|
||||
// Gets the file descriptor into which the PDF will be written.
|
||||
base::FileDescriptor file_descriptor() const { return file_descriptor_; }
|
||||
|
||||
// content::WebContentsObserver implementation.
|
||||
// Terminates or cancels the print job if one was pending.
|
||||
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
|
||||
|
||||
// content::WebContentsObserver implementation.
|
||||
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||
#endif
|
||||
|
||||
private:
|
||||
explicit PrintViewManagerBasic(content::WebContents* web_contents);
|
||||
friend class content::WebContentsUserData<PrintViewManagerBasic>;
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
virtual void OnPrintingFailed(int cookie) OVERRIDE;
|
||||
|
||||
// The file descriptor into which the PDF of the page will be written.
|
||||
base::FileDescriptor file_descriptor_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBasic);
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASIC_H_
|
|
@ -0,0 +1,23 @@
|
|||
// 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_PRINTING_PRINT_VIEW_MANAGER_OBSERVER_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_OBSERVER_H_
|
||||
|
||||
namespace printing {
|
||||
|
||||
// An interface the PrintViewManager uses to notify an observer when the print
|
||||
// dialog is shown. Register the observer via PrintViewManager::set_observer.
|
||||
class PrintViewManagerObserver {
|
||||
public:
|
||||
// Notifies the observer that the print dialog was shown.
|
||||
virtual void OnPrintDialogShown() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~PrintViewManagerObserver() {}
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_OBSERVER_H_
|
143
chromium_src/chrome/browser/printing/printer_query.cc
Normal file
143
chromium_src/chrome/browser/printing/printer_query.cc
Normal file
|
@ -0,0 +1,143 @@
|
|||
// Copyright (c) 2012 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/printing/printer_query.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/bind_helpers.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "base/values.h"
|
||||
#include "chrome/browser/printing/print_job_worker.h"
|
||||
#include "chrome/browser/printing/printing_ui_web_contents_observer.h"
|
||||
|
||||
namespace printing {
|
||||
|
||||
PrinterQuery::PrinterQuery()
|
||||
: io_message_loop_(base::MessageLoop::current()),
|
||||
worker_(new PrintJobWorker(this)),
|
||||
is_print_dialog_box_shown_(false),
|
||||
cookie_(PrintSettings::NewCookie()),
|
||||
last_status_(PrintingContext::FAILED) {
|
||||
DCHECK(base::MessageLoopForIO::IsCurrent());
|
||||
}
|
||||
|
||||
PrinterQuery::~PrinterQuery() {
|
||||
// The job should be finished (or at least canceled) when it is destroyed.
|
||||
DCHECK(!is_print_dialog_box_shown_);
|
||||
// If this fires, it is that this pending printer context has leaked.
|
||||
DCHECK(!worker_.get());
|
||||
}
|
||||
|
||||
void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings,
|
||||
PrintingContext::Result result) {
|
||||
is_print_dialog_box_shown_ = false;
|
||||
last_status_ = result;
|
||||
if (result != PrintingContext::FAILED) {
|
||||
settings_ = new_settings;
|
||||
cookie_ = PrintSettings::NewCookie();
|
||||
} else {
|
||||
// Failure.
|
||||
cookie_ = 0;
|
||||
}
|
||||
|
||||
if (!callback_.is_null()) {
|
||||
// This may cause reentrancy like to call StopWorker().
|
||||
callback_.Run();
|
||||
callback_.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
PrintJobWorker* PrinterQuery::DetachWorker(PrintJobWorkerOwner* new_owner) {
|
||||
DCHECK(callback_.is_null());
|
||||
DCHECK(worker_.get());
|
||||
|
||||
worker_->SetNewOwner(new_owner);
|
||||
return worker_.release();
|
||||
}
|
||||
|
||||
base::MessageLoop* PrinterQuery::message_loop() {
|
||||
return io_message_loop_;
|
||||
}
|
||||
|
||||
const PrintSettings& PrinterQuery::settings() const {
|
||||
return settings_;
|
||||
}
|
||||
|
||||
int PrinterQuery::cookie() const {
|
||||
return cookie_;
|
||||
}
|
||||
|
||||
void PrinterQuery::GetSettings(
|
||||
GetSettingsAskParam ask_user_for_settings,
|
||||
scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
|
||||
int expected_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
const base::Closure& callback) {
|
||||
DCHECK_EQ(io_message_loop_, base::MessageLoop::current());
|
||||
DCHECK(!is_print_dialog_box_shown_);
|
||||
|
||||
StartWorker(callback);
|
||||
|
||||
// Real work is done in PrintJobWorker::GetSettings().
|
||||
is_print_dialog_box_shown_ = ask_user_for_settings == ASK_USER;
|
||||
worker_->message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&PrintJobWorker::GetSettings,
|
||||
base::Unretained(worker_.get()),
|
||||
is_print_dialog_box_shown_,
|
||||
base::Passed(&web_contents_observer),
|
||||
expected_page_count,
|
||||
has_selection,
|
||||
margin_type));
|
||||
}
|
||||
|
||||
void PrinterQuery::SetSettings(const base::DictionaryValue& new_settings,
|
||||
const base::Closure& callback) {
|
||||
StartWorker(callback);
|
||||
|
||||
worker_->message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&PrintJobWorker::SetSettings,
|
||||
base::Unretained(worker_.get()),
|
||||
new_settings.DeepCopy()));
|
||||
}
|
||||
|
||||
void PrinterQuery::SetWorkerDestination(
|
||||
PrintDestinationInterface* destination) {
|
||||
worker_->SetPrintDestination(destination);
|
||||
}
|
||||
|
||||
void PrinterQuery::StartWorker(const base::Closure& callback) {
|
||||
DCHECK(callback_.is_null());
|
||||
DCHECK(worker_.get());
|
||||
|
||||
// Lazily create the worker thread. There is one worker thread per print job.
|
||||
if (!worker_->message_loop())
|
||||
worker_->Start();
|
||||
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
void PrinterQuery::StopWorker() {
|
||||
if (worker_.get()) {
|
||||
// http://crbug.com/66082: We're blocking on the PrinterQuery's worker
|
||||
// thread. It's not clear to me if this may result in blocking the current
|
||||
// thread for an unacceptable time. We should probably fix it.
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
worker_->Stop();
|
||||
worker_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool PrinterQuery::is_callback_pending() const {
|
||||
return !callback_.is_null();
|
||||
}
|
||||
|
||||
bool PrinterQuery::is_valid() const {
|
||||
return worker_.get() != NULL;
|
||||
}
|
||||
|
||||
} // namespace printing
|
110
chromium_src/chrome/browser/printing/printer_query.h
Normal file
110
chromium_src/chrome/browser/printing/printer_query.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
// Copyright (c) 2012 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_PRINTING_PRINTER_QUERY_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINTER_QUERY_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "chrome/browser/printing/print_job_worker_owner.h"
|
||||
#include "printing/print_job_constants.h"
|
||||
|
||||
class PrintingUIWebContentsObserver;
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
class MessageLoop;
|
||||
}
|
||||
|
||||
namespace printing {
|
||||
|
||||
class PrintDestinationInterface;
|
||||
class PrintJobWorker;
|
||||
|
||||
// Query the printer for settings.
|
||||
class PrinterQuery : public PrintJobWorkerOwner {
|
||||
public:
|
||||
// GetSettings() UI parameter.
|
||||
enum GetSettingsAskParam {
|
||||
DEFAULTS,
|
||||
ASK_USER,
|
||||
};
|
||||
|
||||
PrinterQuery();
|
||||
|
||||
// PrintJobWorkerOwner implementation.
|
||||
virtual void GetSettingsDone(const PrintSettings& new_settings,
|
||||
PrintingContext::Result result) OVERRIDE;
|
||||
virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) OVERRIDE;
|
||||
virtual base::MessageLoop* message_loop() OVERRIDE;
|
||||
virtual const PrintSettings& settings() const OVERRIDE;
|
||||
virtual int cookie() const OVERRIDE;
|
||||
|
||||
// Initializes the printing context. It is fine to call this function multiple
|
||||
// times to reinitialize the settings. |web_contents_observer| can be queried
|
||||
// to find the owner of the print setting dialog box. It is unused when
|
||||
// |ask_for_user_settings| is DEFAULTS.
|
||||
void GetSettings(
|
||||
GetSettingsAskParam ask_user_for_settings,
|
||||
scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
|
||||
int expected_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
const base::Closure& callback);
|
||||
|
||||
// Updates the current settings with |new_settings| dictionary values.
|
||||
void SetSettings(const base::DictionaryValue& new_settings,
|
||||
const base::Closure& callback);
|
||||
|
||||
// Set a destination for the worker.
|
||||
void SetWorkerDestination(PrintDestinationInterface* destination);
|
||||
|
||||
// Stops the worker thread since the client is done with this object.
|
||||
void StopWorker();
|
||||
|
||||
// Returns true if a GetSettings() call is pending completion.
|
||||
bool is_callback_pending() const;
|
||||
|
||||
PrintingContext::Result last_status() const { return last_status_; }
|
||||
|
||||
// Returns if a worker thread is still associated to this instance.
|
||||
bool is_valid() const;
|
||||
|
||||
private:
|
||||
virtual ~PrinterQuery();
|
||||
|
||||
// Lazy create the worker thread. There is one worker thread per print job.
|
||||
void StartWorker(const base::Closure& callback);
|
||||
|
||||
// Main message loop reference. Used to send notifications in the right
|
||||
// thread.
|
||||
base::MessageLoop* const io_message_loop_;
|
||||
|
||||
// All the UI is done in a worker thread because many Win32 print functions
|
||||
// are blocking and enters a message loop without your consent. There is one
|
||||
// worker thread per print job.
|
||||
scoped_ptr<PrintJobWorker> worker_;
|
||||
|
||||
// Cache of the print context settings for access in the UI thread.
|
||||
PrintSettings settings_;
|
||||
|
||||
// Is the Print... dialog box currently shown.
|
||||
bool is_print_dialog_box_shown_;
|
||||
|
||||
// Cookie that make this instance unique.
|
||||
int cookie_;
|
||||
|
||||
// Results from the last GetSettingsDone() callback.
|
||||
PrintingContext::Result last_status_;
|
||||
|
||||
// Callback waiting to be run.
|
||||
base::Closure callback_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrinterQuery);
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINTER_QUERY_H_
|
234
chromium_src/chrome/browser/printing/printing_message_filter.cc
Normal file
234
chromium_src/chrome/browser/printing/printing_message_filter.cc
Normal file
|
@ -0,0 +1,234 @@
|
|||
// Copyright (c) 2012 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/printing/printing_message_filter.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/printing/printer_query.h"
|
||||
#include "chrome/browser/printing/print_job_manager.h"
|
||||
#include "chrome/browser/printing/printing_ui_web_contents_observer.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/profiles/profile_io_data.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace {
|
||||
|
||||
void RenderParamsFromPrintSettings(const printing::PrintSettings& settings,
|
||||
PrintMsg_Print_Params* params) {
|
||||
params->page_size = settings.page_setup_device_units().physical_size();
|
||||
params->content_size.SetSize(
|
||||
settings.page_setup_device_units().content_area().width(),
|
||||
settings.page_setup_device_units().content_area().height());
|
||||
params->printable_area.SetRect(
|
||||
settings.page_setup_device_units().printable_area().x(),
|
||||
settings.page_setup_device_units().printable_area().y(),
|
||||
settings.page_setup_device_units().printable_area().width(),
|
||||
settings.page_setup_device_units().printable_area().height());
|
||||
params->margin_top = settings.page_setup_device_units().content_area().y();
|
||||
params->margin_left = settings.page_setup_device_units().content_area().x();
|
||||
params->dpi = settings.dpi();
|
||||
// Currently hardcoded at 1.25. See PrintSettings' constructor.
|
||||
params->min_shrink = settings.min_shrink();
|
||||
// Currently hardcoded at 2.0. See PrintSettings' constructor.
|
||||
params->max_shrink = settings.max_shrink();
|
||||
// Currently hardcoded at 72dpi. See PrintSettings' constructor.
|
||||
params->desired_dpi = settings.desired_dpi();
|
||||
// Always use an invalid cookie.
|
||||
params->document_cookie = 0;
|
||||
params->selection_only = settings.selection_only();
|
||||
params->supports_alpha_blend = settings.supports_alpha_blend();
|
||||
params->should_print_backgrounds = settings.should_print_backgrounds();
|
||||
params->title = settings.title();
|
||||
params->url = settings.url();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PrintingMessageFilter::PrintingMessageFilter(int render_process_id)
|
||||
: BrowserMessageFilter(PrintMsgStart),
|
||||
render_process_id_(render_process_id),
|
||||
queue_(g_browser_process->print_job_manager()->queue()) {
|
||||
DCHECK(queue_);
|
||||
}
|
||||
|
||||
PrintingMessageFilter::~PrintingMessageFilter() {
|
||||
}
|
||||
|
||||
bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message,
|
||||
bool* message_was_ok) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP_EX(PrintingMessageFilter, message, *message_was_ok)
|
||||
#if defined(OS_WIN)
|
||||
IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection)
|
||||
#endif
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
|
||||
OnGetDefaultPrintSettings)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void PrintingMessageFilter::OnDuplicateSection(
|
||||
base::SharedMemoryHandle renderer_handle,
|
||||
base::SharedMemoryHandle* browser_handle) {
|
||||
// Duplicate the handle in this process right now so the memory is kept alive
|
||||
// (even if it is not mapped)
|
||||
base::SharedMemory shared_buf(renderer_handle, true, PeerHandle());
|
||||
shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), browser_handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
content::WebContents* PrintingMessageFilter::GetWebContentsForRenderView(
|
||||
int render_view_id) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
content::RenderViewHost* view = content::RenderViewHost::FromID(
|
||||
render_process_id_, render_view_id);
|
||||
return view ? content::WebContents::FromRenderViewHost(view) : NULL;
|
||||
}
|
||||
|
||||
struct PrintingMessageFilter::GetPrintSettingsForRenderViewParams {
|
||||
printing::PrinterQuery::GetSettingsAskParam ask_user_for_settings;
|
||||
int expected_page_count;
|
||||
bool has_selection;
|
||||
printing::MarginType margin_type;
|
||||
};
|
||||
|
||||
void PrintingMessageFilter::GetPrintSettingsForRenderView(
|
||||
int render_view_id,
|
||||
GetPrintSettingsForRenderViewParams params,
|
||||
const base::Closure& callback,
|
||||
scoped_refptr<printing::PrinterQuery> printer_query) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
|
||||
if (wc) {
|
||||
scoped_ptr<PrintingUIWebContentsObserver> wc_observer(
|
||||
new PrintingUIWebContentsObserver(wc));
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&printing::PrinterQuery::GetSettings, printer_query,
|
||||
params.ask_user_for_settings, base::Passed(&wc_observer),
|
||||
params.expected_page_count, params.has_selection,
|
||||
params.margin_type, callback));
|
||||
} else {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&PrintingMessageFilter::OnGetPrintSettingsFailed, this,
|
||||
callback, printer_query));
|
||||
}
|
||||
}
|
||||
|
||||
void PrintingMessageFilter::OnGetPrintSettingsFailed(
|
||||
const base::Closure& callback,
|
||||
scoped_refptr<printing::PrinterQuery> printer_query) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
printer_query->GetSettingsDone(printing::PrintSettings(),
|
||||
printing::PrintingContext::FAILED);
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
scoped_refptr<printing::PrinterQuery> printer_query;
|
||||
if (false) {
|
||||
// Reply with NULL query.
|
||||
OnGetDefaultPrintSettingsReply(printer_query, reply_msg);
|
||||
return;
|
||||
}
|
||||
printer_query = queue_->PopPrinterQuery(0);
|
||||
if (!printer_query)
|
||||
printer_query = queue_->CreatePrinterQuery();
|
||||
|
||||
// Loads default settings. This is asynchronous, only the IPC message sender
|
||||
// will hang until the settings are retrieved.
|
||||
GetPrintSettingsForRenderViewParams params;
|
||||
params.ask_user_for_settings = printing::PrinterQuery::DEFAULTS;
|
||||
params.expected_page_count = 0;
|
||||
params.has_selection = false;
|
||||
params.margin_type = printing::DEFAULT_MARGINS;
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&PrintingMessageFilter::GetPrintSettingsForRenderView, this,
|
||||
reply_msg->routing_id(), params,
|
||||
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply,
|
||||
this, printer_query, reply_msg),
|
||||
printer_query));
|
||||
}
|
||||
|
||||
void PrintingMessageFilter::OnGetDefaultPrintSettingsReply(
|
||||
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||
IPC::Message* reply_msg) {
|
||||
PrintMsg_Print_Params params;
|
||||
if (!printer_query.get() ||
|
||||
printer_query->last_status() != printing::PrintingContext::OK) {
|
||||
params.Reset();
|
||||
} else {
|
||||
RenderParamsFromPrintSettings(printer_query->settings(), ¶ms);
|
||||
params.document_cookie = printer_query->cookie();
|
||||
}
|
||||
PrintHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, params);
|
||||
Send(reply_msg);
|
||||
// If printing was enabled.
|
||||
if (printer_query.get()) {
|
||||
// If user hasn't cancelled.
|
||||
if (printer_query->cookie() && printer_query->settings().dpi()) {
|
||||
queue_->QueuePrinterQuery(printer_query.get());
|
||||
} else {
|
||||
printer_query->StopWorker();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintingMessageFilter::OnScriptedPrint(
|
||||
const PrintHostMsg_ScriptedPrint_Params& params,
|
||||
IPC::Message* reply_msg) {
|
||||
scoped_refptr<printing::PrinterQuery> printer_query =
|
||||
queue_->PopPrinterQuery(params.cookie);
|
||||
if (!printer_query)
|
||||
printer_query = queue_->CreatePrinterQuery();
|
||||
GetPrintSettingsForRenderViewParams settings_params;
|
||||
settings_params.ask_user_for_settings = printing::PrinterQuery::ASK_USER;
|
||||
settings_params.expected_page_count = params.expected_pages_count;
|
||||
settings_params.has_selection = params.has_selection;
|
||||
settings_params.margin_type = params.margin_type;
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&PrintingMessageFilter::GetPrintSettingsForRenderView, this,
|
||||
reply_msg->routing_id(), settings_params,
|
||||
base::Bind(&PrintingMessageFilter::OnScriptedPrintReply, this,
|
||||
printer_query, reply_msg),
|
||||
printer_query));
|
||||
}
|
||||
|
||||
void PrintingMessageFilter::OnScriptedPrintReply(
|
||||
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||
IPC::Message* reply_msg) {
|
||||
PrintMsg_PrintPages_Params params;
|
||||
if (printer_query->last_status() != printing::PrintingContext::OK ||
|
||||
!printer_query->settings().dpi()) {
|
||||
params.Reset();
|
||||
} else {
|
||||
RenderParamsFromPrintSettings(printer_query->settings(), ¶ms.params);
|
||||
params.params.document_cookie = printer_query->cookie();
|
||||
params.pages =
|
||||
printing::PageRange::GetPages(printer_query->settings().ranges());
|
||||
}
|
||||
PrintHostMsg_ScriptedPrint::WriteReplyParams(reply_msg, params);
|
||||
Send(reply_msg);
|
||||
if (params.params.dpi && params.params.document_cookie) {
|
||||
queue_->QueuePrinterQuery(printer_query.get());
|
||||
} else {
|
||||
printer_query->StopWorker();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright (c) 2012 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_PRINTING_PRINTING_MESSAGE_FILTER_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "content/public/browser/browser_message_filter.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/memory/shared_memory.h"
|
||||
#endif
|
||||
|
||||
struct PrintHostMsg_ScriptedPrint_Params;
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace printing {
|
||||
class PrinterQuery;
|
||||
class PrintJobManager;
|
||||
class PrintQueriesQueue;
|
||||
}
|
||||
|
||||
// This class filters out incoming printing related IPC messages for the
|
||||
// renderer process on the IPC thread.
|
||||
class PrintingMessageFilter : public content::BrowserMessageFilter {
|
||||
public:
|
||||
explicit PrintingMessageFilter(int render_process_id);
|
||||
|
||||
// content::BrowserMessageFilter methods.
|
||||
virtual bool OnMessageReceived(const IPC::Message& message,
|
||||
bool* message_was_ok) OVERRIDE;
|
||||
|
||||
private:
|
||||
virtual ~PrintingMessageFilter();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Used to pass resulting EMF from renderer to browser in printing.
|
||||
void OnDuplicateSection(base::SharedMemoryHandle renderer_handle,
|
||||
base::SharedMemoryHandle* browser_handle);
|
||||
#endif
|
||||
|
||||
// Given a render_view_id get the corresponding WebContents.
|
||||
// Must be called on the UI thread.
|
||||
content::WebContents* GetWebContentsForRenderView(int render_view_id);
|
||||
|
||||
// GetPrintSettingsForRenderView must be called via PostTask and
|
||||
// base::Bind. Collapse the settings-specific params into a
|
||||
// struct to avoid running into issues with too many params
|
||||
// to base::Bind.
|
||||
struct GetPrintSettingsForRenderViewParams;
|
||||
|
||||
// Retrieve print settings. Uses |render_view_id| to get a parent
|
||||
// for any UI created if needed.
|
||||
void GetPrintSettingsForRenderView(
|
||||
int render_view_id,
|
||||
GetPrintSettingsForRenderViewParams params,
|
||||
const base::Closure& callback,
|
||||
scoped_refptr<printing::PrinterQuery> printer_query);
|
||||
|
||||
void OnGetPrintSettingsFailed(
|
||||
const base::Closure& callback,
|
||||
scoped_refptr<printing::PrinterQuery> printer_query);
|
||||
|
||||
// Get the default print setting.
|
||||
void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
|
||||
void OnGetDefaultPrintSettingsReply(
|
||||
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||
IPC::Message* reply_msg);
|
||||
|
||||
// The renderer host have to show to the user the print dialog and returns
|
||||
// the selected print settings. The task is handled by the print worker
|
||||
// thread and the UI thread. The reply occurs on the IO thread.
|
||||
void OnScriptedPrint(const PrintHostMsg_ScriptedPrint_Params& params,
|
||||
IPC::Message* reply_msg);
|
||||
void OnScriptedPrintReply(
|
||||
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||
IPC::Message* reply_msg);
|
||||
|
||||
const int render_process_id_;
|
||||
|
||||
scoped_refptr<printing::PrintQueriesQueue> queue_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintingMessageFilter);
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2013 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/printing/printing_ui_web_contents_observer.h"
|
||||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
PrintingUIWebContentsObserver::PrintingUIWebContentsObserver(
|
||||
content::WebContents* web_contents)
|
||||
: content::WebContentsObserver(web_contents) {
|
||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
||||
}
|
||||
|
||||
gfx::NativeView PrintingUIWebContentsObserver::GetParentView() {
|
||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
||||
return web_contents() ? web_contents()->GetNativeView() : NULL;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2013 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_PRINTING_PRINTING_UI_WEB_CONTENTS_OBSERVER_H_
|
||||
#define CHROME_BROWSER_PRINTING_PRINTING_UI_WEB_CONTENTS_OBSERVER_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
|
||||
// Wrapper used to keep track of the lifetime of a WebContents.
|
||||
// Lives on the UI thread.
|
||||
class PrintingUIWebContentsObserver : public content::WebContentsObserver {
|
||||
public:
|
||||
explicit PrintingUIWebContentsObserver(content::WebContents* web_contents);
|
||||
|
||||
// Return the parent NativeView of the observed WebContents.
|
||||
gfx::NativeView GetParentView();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintingUIWebContentsObserver);
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_PRINTING_PRINTING_UI_WEB_CONTENTS_OBSERVER_H_
|
0
chromium_src/chrome/browser/profiles/profile.h
Normal file
0
chromium_src/chrome/browser/profiles/profile.h
Normal file
0
chromium_src/chrome/browser/profiles/profile_io_data.h
Normal file
0
chromium_src/chrome/browser/profiles/profile_io_data.h
Normal file
0
chromium_src/chrome/browser/ui/simple_message_box.h
Normal file
0
chromium_src/chrome/browser/ui/simple_message_box.h
Normal file
0
chromium_src/chrome/common/pref_names.h
Normal file
0
chromium_src/chrome/common/pref_names.h
Normal file
60
chromium_src/chrome/common/print_messages.cc
Normal file
60
chromium_src/chrome/common/print_messages.cc
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2012 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/common/print_messages.h"
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "ui/gfx/size.h"
|
||||
|
||||
PrintMsg_Print_Params::PrintMsg_Print_Params()
|
||||
: page_size(),
|
||||
content_size(),
|
||||
printable_area(),
|
||||
margin_top(0),
|
||||
margin_left(0),
|
||||
dpi(0),
|
||||
min_shrink(0),
|
||||
max_shrink(0),
|
||||
desired_dpi(0),
|
||||
document_cookie(0),
|
||||
selection_only(false),
|
||||
supports_alpha_blend(false),
|
||||
print_scaling_option(blink::WebPrintScalingOptionSourceSize),
|
||||
title(),
|
||||
url(),
|
||||
should_print_backgrounds(false) {
|
||||
}
|
||||
|
||||
PrintMsg_Print_Params::~PrintMsg_Print_Params() {}
|
||||
|
||||
void PrintMsg_Print_Params::Reset() {
|
||||
page_size = gfx::Size();
|
||||
content_size = gfx::Size();
|
||||
printable_area = gfx::Rect();
|
||||
margin_top = 0;
|
||||
margin_left = 0;
|
||||
dpi = 0;
|
||||
min_shrink = 0;
|
||||
max_shrink = 0;
|
||||
desired_dpi = 0;
|
||||
document_cookie = 0;
|
||||
selection_only = false;
|
||||
supports_alpha_blend = false;
|
||||
print_scaling_option = blink::WebPrintScalingOptionSourceSize;
|
||||
title.clear();
|
||||
url.clear();
|
||||
should_print_backgrounds = false;
|
||||
}
|
||||
|
||||
PrintMsg_PrintPages_Params::PrintMsg_PrintPages_Params()
|
||||
: pages() {
|
||||
}
|
||||
|
||||
PrintMsg_PrintPages_Params::~PrintMsg_PrintPages_Params() {}
|
||||
|
||||
void PrintMsg_PrintPages_Params::Reset() {
|
||||
params.Reset();
|
||||
pages = std::vector<int>();
|
||||
}
|
241
chromium_src/chrome/common/print_messages.h
Normal file
241
chromium_src/chrome/common/print_messages.h
Normal file
|
@ -0,0 +1,241 @@
|
|||
// Copyright (c) 2012 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.
|
||||
|
||||
// IPC messages for printing.
|
||||
// Multiply-included message file, hence no include guard.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/shared_memory.h"
|
||||
#include "base/values.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "printing/page_size_margins.h"
|
||||
#include "printing/print_job_constants.h"
|
||||
#include "third_party/WebKit/public/web/WebPrintScalingOption.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
|
||||
#ifndef CHROME_COMMON_PRINT_MESSAGES_H_
|
||||
#define CHROME_COMMON_PRINT_MESSAGES_H_
|
||||
|
||||
struct PrintMsg_Print_Params {
|
||||
PrintMsg_Print_Params();
|
||||
~PrintMsg_Print_Params();
|
||||
|
||||
// Resets the members of the struct to 0.
|
||||
void Reset();
|
||||
|
||||
gfx::Size page_size;
|
||||
gfx::Size content_size;
|
||||
gfx::Rect printable_area;
|
||||
int margin_top;
|
||||
int margin_left;
|
||||
double dpi;
|
||||
double min_shrink;
|
||||
double max_shrink;
|
||||
int desired_dpi;
|
||||
int document_cookie;
|
||||
bool selection_only;
|
||||
bool supports_alpha_blend;
|
||||
blink::WebPrintScalingOption print_scaling_option;
|
||||
base::string16 title;
|
||||
base::string16 url;
|
||||
bool should_print_backgrounds;
|
||||
};
|
||||
|
||||
struct PrintMsg_PrintPages_Params {
|
||||
PrintMsg_PrintPages_Params();
|
||||
~PrintMsg_PrintPages_Params();
|
||||
|
||||
// Resets the members of the struct to 0.
|
||||
void Reset();
|
||||
|
||||
PrintMsg_Print_Params params;
|
||||
std::vector<int> pages;
|
||||
};
|
||||
|
||||
#endif // CHROME_COMMON_PRINT_MESSAGES_H_
|
||||
|
||||
#define IPC_MESSAGE_START PrintMsgStart
|
||||
|
||||
IPC_ENUM_TRAITS_MAX_VALUE(printing::MarginType,
|
||||
printing::MARGIN_TYPE_LAST)
|
||||
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPrintScalingOption,
|
||||
blink::WebPrintScalingOptionLast)
|
||||
|
||||
// Parameters for a render request.
|
||||
IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params)
|
||||
// Physical size of the page, including non-printable margins,
|
||||
// in pixels according to dpi.
|
||||
IPC_STRUCT_TRAITS_MEMBER(page_size)
|
||||
|
||||
// In pixels according to dpi_x and dpi_y.
|
||||
IPC_STRUCT_TRAITS_MEMBER(content_size)
|
||||
|
||||
// Physical printable area of the page in pixels according to dpi.
|
||||
IPC_STRUCT_TRAITS_MEMBER(printable_area)
|
||||
|
||||
// The y-offset of the printable area, in pixels according to dpi.
|
||||
IPC_STRUCT_TRAITS_MEMBER(margin_top)
|
||||
|
||||
// The x-offset of the printable area, in pixels according to dpi.
|
||||
IPC_STRUCT_TRAITS_MEMBER(margin_left)
|
||||
|
||||
// Specifies dots per inch.
|
||||
IPC_STRUCT_TRAITS_MEMBER(dpi)
|
||||
|
||||
// Minimum shrink factor. See PrintSettings::min_shrink for more information.
|
||||
IPC_STRUCT_TRAITS_MEMBER(min_shrink)
|
||||
|
||||
// Maximum shrink factor. See PrintSettings::max_shrink for more information.
|
||||
IPC_STRUCT_TRAITS_MEMBER(max_shrink)
|
||||
|
||||
// Desired apparent dpi on paper.
|
||||
IPC_STRUCT_TRAITS_MEMBER(desired_dpi)
|
||||
|
||||
// Cookie for the document to ensure correctness.
|
||||
IPC_STRUCT_TRAITS_MEMBER(document_cookie)
|
||||
|
||||
// Should only print currently selected text.
|
||||
IPC_STRUCT_TRAITS_MEMBER(selection_only)
|
||||
|
||||
// Does the printer support alpha blending?
|
||||
IPC_STRUCT_TRAITS_MEMBER(supports_alpha_blend)
|
||||
|
||||
// Specifies the page scaling option for preview printing.
|
||||
IPC_STRUCT_TRAITS_MEMBER(print_scaling_option)
|
||||
|
||||
// Title string to be printed as header if requested by the user.
|
||||
IPC_STRUCT_TRAITS_MEMBER(title)
|
||||
|
||||
// URL string to be printed as footer if requested by the user.
|
||||
IPC_STRUCT_TRAITS_MEMBER(url)
|
||||
|
||||
// True if print backgrounds is requested by the user.
|
||||
IPC_STRUCT_TRAITS_MEMBER(should_print_backgrounds)
|
||||
IPC_STRUCT_TRAITS_END()
|
||||
|
||||
IPC_STRUCT_BEGIN(PrintMsg_PrintPage_Params)
|
||||
// Parameters to render the page as a printed page. It must always be the same
|
||||
// value for all the document.
|
||||
IPC_STRUCT_MEMBER(PrintMsg_Print_Params, params)
|
||||
|
||||
// The page number is the indicator of the square that should be rendered
|
||||
// according to the layout specified in PrintMsg_Print_Params.
|
||||
IPC_STRUCT_MEMBER(int, page_number)
|
||||
IPC_STRUCT_END()
|
||||
|
||||
IPC_STRUCT_TRAITS_BEGIN(printing::PageSizeMargins)
|
||||
IPC_STRUCT_TRAITS_MEMBER(content_width)
|
||||
IPC_STRUCT_TRAITS_MEMBER(content_height)
|
||||
IPC_STRUCT_TRAITS_MEMBER(margin_left)
|
||||
IPC_STRUCT_TRAITS_MEMBER(margin_right)
|
||||
IPC_STRUCT_TRAITS_MEMBER(margin_top)
|
||||
IPC_STRUCT_TRAITS_MEMBER(margin_bottom)
|
||||
IPC_STRUCT_TRAITS_END()
|
||||
|
||||
IPC_STRUCT_TRAITS_BEGIN(PrintMsg_PrintPages_Params)
|
||||
// Parameters to render the page as a printed page. It must always be the same
|
||||
// value for all the document.
|
||||
IPC_STRUCT_TRAITS_MEMBER(params)
|
||||
|
||||
// If empty, this means a request to render all the printed pages.
|
||||
IPC_STRUCT_TRAITS_MEMBER(pages)
|
||||
IPC_STRUCT_TRAITS_END()
|
||||
|
||||
// Parameters to describe a rendered page.
|
||||
IPC_STRUCT_BEGIN(PrintHostMsg_DidPrintPage_Params)
|
||||
// A shared memory handle to the EMF data. This data can be quite large so a
|
||||
// memory map needs to be used.
|
||||
IPC_STRUCT_MEMBER(base::SharedMemoryHandle, metafile_data_handle)
|
||||
|
||||
// Size of the metafile data.
|
||||
IPC_STRUCT_MEMBER(uint32, data_size)
|
||||
|
||||
// Cookie for the document to ensure correctness.
|
||||
IPC_STRUCT_MEMBER(int, document_cookie)
|
||||
|
||||
// Page number.
|
||||
IPC_STRUCT_MEMBER(int, page_number)
|
||||
|
||||
// Shrink factor used to render this page.
|
||||
IPC_STRUCT_MEMBER(double, actual_shrink)
|
||||
|
||||
// The size of the page the page author specified.
|
||||
IPC_STRUCT_MEMBER(gfx::Size, page_size)
|
||||
|
||||
// The printable area the page author specified.
|
||||
IPC_STRUCT_MEMBER(gfx::Rect, content_area)
|
||||
IPC_STRUCT_END()
|
||||
|
||||
// Parameters for the IPC message ViewHostMsg_ScriptedPrint
|
||||
IPC_STRUCT_BEGIN(PrintHostMsg_ScriptedPrint_Params)
|
||||
IPC_STRUCT_MEMBER(int, cookie)
|
||||
IPC_STRUCT_MEMBER(int, expected_pages_count)
|
||||
IPC_STRUCT_MEMBER(bool, has_selection)
|
||||
IPC_STRUCT_MEMBER(printing::MarginType, margin_type)
|
||||
IPC_STRUCT_END()
|
||||
|
||||
|
||||
// Messages sent from the browser to the renderer.
|
||||
|
||||
// Tells the render view to switch the CSS to print media type, renders every
|
||||
// requested pages and switch back the CSS to display media type.
|
||||
IPC_MESSAGE_ROUTED2(PrintMsg_PrintPages,
|
||||
bool /* silent print */,
|
||||
bool /* print page's background */)
|
||||
|
||||
// Tells the render view that printing is done so it can clean up.
|
||||
IPC_MESSAGE_ROUTED1(PrintMsg_PrintingDone,
|
||||
bool /* success */)
|
||||
|
||||
// Messages sent from the renderer to the browser.
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Duplicates a shared memory handle from the renderer to the browser. Then
|
||||
// the renderer can flush the handle.
|
||||
IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_DuplicateSection,
|
||||
base::SharedMemoryHandle /* renderer handle */,
|
||||
base::SharedMemoryHandle /* browser handle */)
|
||||
#endif
|
||||
|
||||
// Tells the browser that the renderer is done calculating the number of
|
||||
// rendered pages according to the specified settings.
|
||||
IPC_MESSAGE_ROUTED2(PrintHostMsg_DidGetPrintedPagesCount,
|
||||
int /* rendered document cookie */,
|
||||
int /* number of rendered pages */)
|
||||
|
||||
// Sends the document cookie of the current printer query to the browser.
|
||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetDocumentCookie,
|
||||
int /* rendered document cookie */)
|
||||
|
||||
// Tells the browser that the print dialog has been shown.
|
||||
IPC_MESSAGE_ROUTED0(PrintHostMsg_DidShowPrintDialog)
|
||||
|
||||
// Sends back to the browser the rendered "printed page" that was requested by
|
||||
// a ViewMsg_PrintPage message or from scripted printing. The memory handle in
|
||||
// this message is already valid in the browser process.
|
||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPrintPage,
|
||||
PrintHostMsg_DidPrintPage_Params /* page content */)
|
||||
|
||||
// The renderer wants to know the default print settings.
|
||||
IPC_SYNC_MESSAGE_ROUTED0_1(PrintHostMsg_GetDefaultPrintSettings,
|
||||
PrintMsg_Print_Params /* default_settings */)
|
||||
|
||||
// It's the renderer that controls the printing process when it is generated
|
||||
// by javascript. This step is about showing UI to the user to select the
|
||||
// final print settings. The output parameter is the same as
|
||||
// ViewMsg_PrintPages which is executed implicitly.
|
||||
IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_ScriptedPrint,
|
||||
PrintHostMsg_ScriptedPrint_Params,
|
||||
PrintMsg_PrintPages_Params
|
||||
/* settings chosen by the user*/)
|
||||
|
||||
// This is sent when there are invalid printer settings.
|
||||
IPC_MESSAGE_ROUTED0(PrintHostMsg_ShowInvalidPrinterSettingsError)
|
||||
|
||||
// Tell the browser printing failed.
|
||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed,
|
||||
int /* document cookie */)
|
1001
chromium_src/chrome/renderer/printing/print_web_view_helper.cc
Normal file
1001
chromium_src/chrome/renderer/printing/print_web_view_helper.cc
Normal file
File diff suppressed because it is too large
Load diff
218
chromium_src/chrome/renderer/printing/print_web_view_helper.h
Normal file
218
chromium_src/chrome/renderer/printing/print_web_view_helper.h
Normal file
|
@ -0,0 +1,218 @@
|
|||
// Copyright (c) 2012 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_RENDERER_PRINTING_PRINT_WEB_VIEW_HELPER_H_
|
||||
#define CHROME_RENDERER_PRINTING_PRINT_WEB_VIEW_HELPER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/shared_memory.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/time/time.h"
|
||||
#include "content/public/renderer/render_view_observer.h"
|
||||
#include "content/public/renderer/render_view_observer_tracker.h"
|
||||
#include "printing/metafile_impl.h"
|
||||
#include "third_party/WebKit/public/platform/WebCanvas.h"
|
||||
#include "third_party/WebKit/public/web/WebNode.h"
|
||||
#include "third_party/WebKit/public/web/WebPrintParams.h"
|
||||
#include "ui/gfx/size.h"
|
||||
|
||||
struct PrintMsg_Print_Params;
|
||||
struct PrintMsg_PrintPage_Params;
|
||||
struct PrintMsg_PrintPages_Params;
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace blink {
|
||||
class WebFrame;
|
||||
class WebView;
|
||||
}
|
||||
|
||||
namespace printing {
|
||||
|
||||
struct PageSizeMargins;
|
||||
class PrepareFrameAndViewForPrint;
|
||||
|
||||
// Stores reference to frame using WebVew and unique name.
|
||||
// Workaround to modal dialog issue on Linux. crbug.com/236147.
|
||||
// If WebFrame someday supports WeakPtr, we should use it here.
|
||||
class FrameReference {
|
||||
public:
|
||||
explicit FrameReference(blink::WebLocalFrame* frame);
|
||||
FrameReference();
|
||||
~FrameReference();
|
||||
|
||||
void Reset(blink::WebLocalFrame* frame);
|
||||
|
||||
blink::WebLocalFrame* GetFrame();
|
||||
blink::WebView* view();
|
||||
|
||||
private:
|
||||
blink::WebView* view_;
|
||||
blink::WebLocalFrame* frame_;
|
||||
};
|
||||
|
||||
// PrintWebViewHelper handles most of the printing grunt work for RenderView.
|
||||
// We plan on making print asynchronous and that will require copying the DOM
|
||||
// of the document and creating a new WebView with the contents.
|
||||
class PrintWebViewHelper
|
||||
: public content::RenderViewObserver,
|
||||
public content::RenderViewObserverTracker<PrintWebViewHelper> {
|
||||
public:
|
||||
explicit PrintWebViewHelper(content::RenderView* render_view);
|
||||
virtual ~PrintWebViewHelper();
|
||||
|
||||
void PrintNode(const blink::WebNode& node);
|
||||
|
||||
private:
|
||||
enum PrintingResult {
|
||||
OK,
|
||||
FAIL_PRINT_INIT,
|
||||
FAIL_PRINT,
|
||||
};
|
||||
|
||||
// RenderViewObserver implementation.
|
||||
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||
virtual void PrintPage(blink::WebLocalFrame* frame,
|
||||
bool user_initiated) OVERRIDE;
|
||||
|
||||
// Message handlers ---------------------------------------------------------
|
||||
void OnPrintPages(bool silent, bool print_background);
|
||||
void OnPrintingDone(bool success);
|
||||
|
||||
// Get |page_size| and |content_area| information from
|
||||
// |page_layout_in_points|.
|
||||
void GetPageSizeAndContentAreaFromPageLayout(
|
||||
const PageSizeMargins& page_layout_in_points,
|
||||
gfx::Size* page_size,
|
||||
gfx::Rect* content_area);
|
||||
|
||||
// Update |ignore_css_margins_| based on settings.
|
||||
void UpdateFrameMarginsCssInfo(const base::DictionaryValue& settings);
|
||||
|
||||
// Main printing code -------------------------------------------------------
|
||||
|
||||
void Print(blink::WebLocalFrame* frame,
|
||||
const blink::WebNode& node,
|
||||
bool silent = false,
|
||||
bool print_background = false);
|
||||
|
||||
// Notification when printing is done - signal tear-down/free resources.
|
||||
void DidFinishPrinting(PrintingResult result);
|
||||
|
||||
// Print Settings -----------------------------------------------------------
|
||||
|
||||
// Initialize print page settings with default settings.
|
||||
// Used only for native printing workflow.
|
||||
bool InitPrintSettings(bool fit_to_paper_size);
|
||||
|
||||
// Calculate number of pages in source document.
|
||||
bool CalculateNumberOfPages(blink::WebLocalFrame* frame,
|
||||
const blink::WebNode& node,
|
||||
int* number_of_pages);
|
||||
|
||||
// Get final print settings from the user.
|
||||
// Return false if the user cancels or on error.
|
||||
bool GetPrintSettingsFromUser(blink::WebFrame* frame,
|
||||
const blink::WebNode& node,
|
||||
int expected_pages_count);
|
||||
|
||||
// Page Printing / Rendering ------------------------------------------------
|
||||
|
||||
void OnFramePreparedForPrintPages();
|
||||
void PrintPages();
|
||||
bool PrintPagesNative(blink::WebFrame* frame,
|
||||
int page_count,
|
||||
const gfx::Size& canvas_size);
|
||||
void FinishFramePrinting();
|
||||
|
||||
// Prints the page listed in |params|.
|
||||
#if defined(OS_LINUX) || defined(OS_ANDROID)
|
||||
void PrintPageInternal(const PrintMsg_PrintPage_Params& params,
|
||||
const gfx::Size& canvas_size,
|
||||
blink::WebFrame* frame,
|
||||
Metafile* metafile);
|
||||
#else
|
||||
void PrintPageInternal(const PrintMsg_PrintPage_Params& params,
|
||||
const gfx::Size& canvas_size,
|
||||
blink::WebFrame* frame);
|
||||
#endif
|
||||
|
||||
// Render the frame for printing.
|
||||
bool RenderPagesForPrint(blink::WebLocalFrame* frame,
|
||||
const blink::WebNode& node);
|
||||
|
||||
// Platform specific helper function for rendering page(s) to |metafile|.
|
||||
#if defined(OS_WIN)
|
||||
void RenderPage(const PrintMsg_Print_Params& params,
|
||||
int page_number,
|
||||
blink::WebFrame* frame,
|
||||
bool is_preview,
|
||||
Metafile* metafile,
|
||||
double* scale_factor,
|
||||
gfx::Size* page_size_in_dpi,
|
||||
gfx::Rect* content_area_in_dpi);
|
||||
#elif defined(OS_MACOSX)
|
||||
void RenderPage(const PrintMsg_Print_Params& params,
|
||||
int page_number,
|
||||
blink::WebFrame* frame,
|
||||
bool is_preview,
|
||||
Metafile* metafile,
|
||||
gfx::Size* page_size,
|
||||
gfx::Rect* content_rect);
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
// Renders page contents from |frame| to |content_area| of |canvas|.
|
||||
// |page_number| is zero-based.
|
||||
// When method is called, canvas should be setup to draw to |canvas_area|
|
||||
// with |scale_factor|.
|
||||
static float RenderPageContent(blink::WebFrame* frame,
|
||||
int page_number,
|
||||
const gfx::Rect& canvas_area,
|
||||
const gfx::Rect& content_area,
|
||||
double scale_factor,
|
||||
blink::WebCanvas* canvas);
|
||||
|
||||
// Helper methods -----------------------------------------------------------
|
||||
|
||||
bool CopyMetafileDataToSharedMem(Metafile* metafile,
|
||||
base::SharedMemoryHandle* shared_mem_handle);
|
||||
|
||||
// Helper method to get page layout in points and fit to page if needed.
|
||||
static void ComputePageLayoutInPointsForCss(
|
||||
blink::WebFrame* frame,
|
||||
int page_index,
|
||||
const PrintMsg_Print_Params& default_params,
|
||||
bool ignore_css_margins,
|
||||
double* scale_factor,
|
||||
PageSizeMargins* page_layout_in_points);
|
||||
|
||||
bool GetPrintFrame(blink::WebLocalFrame** frame);
|
||||
|
||||
// Script Initiated Printing ------------------------------------------------
|
||||
|
||||
// WebView used only to print the selection.
|
||||
scoped_ptr<PrepareFrameAndViewForPrint> prep_frame_view_;
|
||||
|
||||
scoped_ptr<PrintMsg_PrintPages_Params> print_pages_params_;
|
||||
bool is_print_ready_metafile_sent_;
|
||||
bool ignore_css_margins_;
|
||||
|
||||
// Let the browser process know of a printing failure. Only set to false when
|
||||
// the failure came from the browser in the first place.
|
||||
bool notify_browser_of_print_failure_;
|
||||
|
||||
bool print_node_in_progress_;
|
||||
|
||||
base::WeakPtrFactory<PrintWebViewHelper> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper);
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // CHROME_RENDERER_PRINTING_PRINT_WEB_VIEW_HELPER_H_
|
|
@ -0,0 +1,157 @@
|
|||
// Copyright (c) 2012 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/renderer/printing/print_web_view_helper.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "printing/metafile.h"
|
||||
#include "printing/metafile_impl.h"
|
||||
#include "printing/metafile_skia_wrapper.h"
|
||||
#include "printing/page_size_margins.h"
|
||||
#include "skia/ext/platform_device.h"
|
||||
#include "skia/ext/vector_canvas.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
|
||||
#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
|
||||
#include "base/process/process_handle.h"
|
||||
#else
|
||||
#include "base/file_descriptor_posix.h"
|
||||
#endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
|
||||
|
||||
namespace printing {
|
||||
|
||||
using blink::WebFrame;
|
||||
|
||||
bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame,
|
||||
int page_count,
|
||||
const gfx::Size& canvas_size) {
|
||||
NativeMetafile metafile;
|
||||
if (!metafile.Init())
|
||||
return false;
|
||||
|
||||
const PrintMsg_PrintPages_Params& params = *print_pages_params_;
|
||||
std::vector<int> printed_pages;
|
||||
|
||||
if (params.pages.empty()) {
|
||||
for (int i = 0; i < page_count; ++i) {
|
||||
printed_pages.push_back(i);
|
||||
}
|
||||
} else {
|
||||
// TODO(vitalybuka): redesign to make more code cross platform.
|
||||
for (size_t i = 0; i < params.pages.size(); ++i) {
|
||||
if (params.pages[i] >= 0 && params.pages[i] < page_count) {
|
||||
printed_pages.push_back(params.pages[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (printed_pages.empty())
|
||||
return false;
|
||||
|
||||
PrintMsg_PrintPage_Params page_params;
|
||||
page_params.params = params.params;
|
||||
for (size_t i = 0; i < printed_pages.size(); ++i) {
|
||||
page_params.page_number = printed_pages[i];
|
||||
PrintPageInternal(page_params, canvas_size, frame, &metafile);
|
||||
}
|
||||
|
||||
// blink::printEnd() for PDF should be called before metafile is closed.
|
||||
FinishFramePrinting();
|
||||
|
||||
metafile.FinishDocument();
|
||||
|
||||
// Get the size of the resulting metafile.
|
||||
uint32 buf_size = metafile.GetDataSize();
|
||||
DCHECK_GT(buf_size, 0u);
|
||||
|
||||
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
|
||||
int sequence_number = -1;
|
||||
base::FileDescriptor fd;
|
||||
|
||||
// Ask the browser to open a file for us.
|
||||
Send(new PrintHostMsg_AllocateTempFileForPrinting(routing_id(),
|
||||
&fd,
|
||||
&sequence_number));
|
||||
if (!metafile.SaveToFD(fd))
|
||||
return false;
|
||||
|
||||
// Tell the browser we've finished writing the file.
|
||||
Send(new PrintHostMsg_TempFileForPrintingWritten(routing_id(),
|
||||
sequence_number));
|
||||
return true;
|
||||
#else
|
||||
PrintHostMsg_DidPrintPage_Params printed_page_params;
|
||||
printed_page_params.data_size = 0;
|
||||
printed_page_params.document_cookie = params.params.document_cookie;
|
||||
|
||||
{
|
||||
scoped_ptr<base::SharedMemory> shared_mem(
|
||||
content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(
|
||||
buf_size).release());
|
||||
if (!shared_mem.get()) {
|
||||
NOTREACHED() << "AllocateSharedMemoryBuffer failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!shared_mem->Map(buf_size)) {
|
||||
NOTREACHED() << "Map failed";
|
||||
return false;
|
||||
}
|
||||
metafile.GetData(shared_mem->memory(), buf_size);
|
||||
printed_page_params.data_size = buf_size;
|
||||
shared_mem->GiveToProcess(base::GetCurrentProcessHandle(),
|
||||
&(printed_page_params.metafile_data_handle));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < printed_pages.size(); ++i) {
|
||||
printed_page_params.page_number = printed_pages[i];
|
||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
|
||||
// Send the rest of the pages with an invalid metafile handle.
|
||||
printed_page_params.metafile_data_handle.fd = -1;
|
||||
}
|
||||
return true;
|
||||
#endif // defined(OS_CHROMEOS)
|
||||
}
|
||||
|
||||
void PrintWebViewHelper::PrintPageInternal(
|
||||
const PrintMsg_PrintPage_Params& params,
|
||||
const gfx::Size& canvas_size,
|
||||
WebFrame* frame,
|
||||
Metafile* metafile) {
|
||||
PageSizeMargins page_layout_in_points;
|
||||
double scale_factor = 1.0f;
|
||||
ComputePageLayoutInPointsForCss(frame, params.page_number, params.params,
|
||||
ignore_css_margins_, &scale_factor,
|
||||
&page_layout_in_points);
|
||||
gfx::Size page_size;
|
||||
gfx::Rect content_area;
|
||||
GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, &page_size,
|
||||
&content_area);
|
||||
gfx::Rect canvas_area = content_area;
|
||||
|
||||
SkBaseDevice* device = metafile->StartPageForVectorCanvas(page_size,
|
||||
canvas_area,
|
||||
scale_factor);
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
// The printPage method take a reference to the canvas we pass down, so it
|
||||
// can't be a stack object.
|
||||
skia::RefPtr<skia::VectorCanvas> canvas =
|
||||
skia::AdoptRef(new skia::VectorCanvas(device));
|
||||
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
|
||||
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
|
||||
|
||||
RenderPageContent(frame, params.page_number, canvas_area, content_area,
|
||||
scale_factor, canvas.get());
|
||||
|
||||
// Done printing. Close the device context to retrieve the compiled metafile.
|
||||
if (!metafile->FinishPage())
|
||||
NOTREACHED() << "metafile failed";
|
||||
}
|
||||
|
||||
} // namespace printing
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright (c) 2012 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/renderer/printing/print_web_view_helper.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "printing/metafile.h"
|
||||
#include "printing/metafile_impl.h"
|
||||
#include "printing/metafile_skia_wrapper.h"
|
||||
#include "printing/page_size_margins.h"
|
||||
#include "skia/ext/platform_device.h"
|
||||
#include "skia/ext/vector_canvas.h"
|
||||
#include "third_party/WebKit/public/platform/WebCanvas.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
|
||||
namespace printing {
|
||||
|
||||
using blink::WebFrame;
|
||||
|
||||
void PrintWebViewHelper::PrintPageInternal(
|
||||
const PrintMsg_PrintPage_Params& params,
|
||||
const gfx::Size& canvas_size,
|
||||
WebFrame* frame) {
|
||||
NativeMetafile metafile;
|
||||
if (!metafile.Init())
|
||||
return;
|
||||
|
||||
int page_number = params.page_number;
|
||||
gfx::Size page_size_in_dpi;
|
||||
gfx::Rect content_area_in_dpi;
|
||||
RenderPage(print_pages_params_->params, page_number, frame, false, &metafile,
|
||||
&page_size_in_dpi, &content_area_in_dpi);
|
||||
metafile.FinishDocument();
|
||||
|
||||
PrintHostMsg_DidPrintPage_Params page_params;
|
||||
page_params.data_size = metafile.GetDataSize();
|
||||
page_params.page_number = page_number;
|
||||
page_params.document_cookie = params.params.document_cookie;
|
||||
page_params.page_size = page_size_in_dpi;
|
||||
page_params.content_area = content_area_in_dpi;
|
||||
|
||||
// Ask the browser to create the shared memory for us.
|
||||
if (!CopyMetafileDataToSharedMem(&metafile,
|
||||
&(page_params.metafile_data_handle))) {
|
||||
page_params.data_size = 0;
|
||||
}
|
||||
|
||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params));
|
||||
}
|
||||
|
||||
void PrintWebViewHelper::RenderPage(
|
||||
const PrintMsg_Print_Params& params, int page_number, WebFrame* frame,
|
||||
bool is_preview, Metafile* metafile, gfx::Size* page_size,
|
||||
gfx::Rect* content_rect) {
|
||||
double scale_factor = 1.0f;
|
||||
double webkit_shrink_factor = frame->getPrintPageShrink(page_number);
|
||||
PageSizeMargins page_layout_in_points;
|
||||
gfx::Rect content_area;
|
||||
|
||||
ComputePageLayoutInPointsForCss(frame, page_number, params,
|
||||
ignore_css_margins_, &scale_factor,
|
||||
&page_layout_in_points);
|
||||
GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, page_size,
|
||||
&content_area);
|
||||
if (content_rect)
|
||||
*content_rect = content_area;
|
||||
|
||||
scale_factor *= webkit_shrink_factor;
|
||||
|
||||
gfx::Rect canvas_area = content_area;
|
||||
|
||||
{
|
||||
SkBaseDevice* device = metafile->StartPageForVectorCanvas(
|
||||
*page_size, canvas_area, scale_factor);
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
skia::RefPtr<skia::VectorCanvas> canvas =
|
||||
skia::AdoptRef(new skia::VectorCanvas(device));
|
||||
blink::WebCanvas* canvas_ptr = canvas.get();
|
||||
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
|
||||
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
|
||||
skia::SetIsPreviewMetafile(*canvas, is_preview);
|
||||
|
||||
RenderPageContent(frame, page_number, canvas_area, content_area,
|
||||
scale_factor, canvas_ptr);
|
||||
}
|
||||
|
||||
// Done printing. Close the device context to retrieve the compiled metafile.
|
||||
metafile->FinishPage();
|
||||
}
|
||||
|
||||
} // namespace printing
|
|
@ -0,0 +1,193 @@
|
|||
// Copyright (c) 2012 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/renderer/printing/print_web_view_helper.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "base/process/process_handle.h"
|
||||
#include "base/win/scoped_gdi_object.h"
|
||||
#include "base/win/scoped_hdc.h"
|
||||
#include "base/win/scoped_select_object.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "printing/metafile.h"
|
||||
#include "printing/metafile_impl.h"
|
||||
#include "printing/metafile_skia_wrapper.h"
|
||||
#include "printing/page_size_margins.h"
|
||||
#include "printing/units.h"
|
||||
#include "skia/ext/platform_device.h"
|
||||
#include "skia/ext/refptr.h"
|
||||
#include "skia/ext/vector_canvas.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
#include "ui/gfx/gdi_util.h"
|
||||
#include "ui/gfx/point.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/gfx/size.h"
|
||||
|
||||
namespace printing {
|
||||
|
||||
using blink::WebFrame;
|
||||
|
||||
void PrintWebViewHelper::PrintPageInternal(
|
||||
const PrintMsg_PrintPage_Params& params,
|
||||
const gfx::Size& canvas_size,
|
||||
WebFrame* frame) {
|
||||
// Generate a memory-based metafile. It will use the current screen's DPI.
|
||||
// Each metafile contains a single page.
|
||||
scoped_ptr<NativeMetafile> metafile(new NativeMetafile);
|
||||
metafile->Init();
|
||||
DCHECK(metafile->context());
|
||||
skia::InitializeDC(metafile->context());
|
||||
|
||||
int page_number = params.page_number;
|
||||
|
||||
// Calculate the dpi adjustment.
|
||||
// Browser will render context using desired_dpi, so we need to calculate
|
||||
// adjustment factor to play content on the printer DC later during the
|
||||
// actual printing.
|
||||
double actual_shrink = static_cast<float>(params.params.desired_dpi /
|
||||
params.params.dpi);
|
||||
gfx::Size page_size_in_dpi;
|
||||
gfx::Rect content_area_in_dpi;
|
||||
|
||||
// Render page for printing.
|
||||
RenderPage(params.params, page_number, frame, false, metafile.get(),
|
||||
&actual_shrink, &page_size_in_dpi, &content_area_in_dpi);
|
||||
|
||||
// Close the device context to retrieve the compiled metafile.
|
||||
if (!metafile->FinishDocument())
|
||||
NOTREACHED();
|
||||
|
||||
if (!params.params.supports_alpha_blend && metafile->IsAlphaBlendUsed()) {
|
||||
scoped_ptr<NativeMetafile> raster_metafile(
|
||||
metafile->RasterizeAlphaBlend());
|
||||
if (raster_metafile.get())
|
||||
metafile.swap(raster_metafile);
|
||||
}
|
||||
|
||||
// Get the size of the compiled metafile.
|
||||
uint32 buf_size = metafile->GetDataSize();
|
||||
DCHECK_GT(buf_size, 128u);
|
||||
|
||||
PrintHostMsg_DidPrintPage_Params page_params;
|
||||
page_params.data_size = buf_size;
|
||||
page_params.metafile_data_handle = NULL;
|
||||
page_params.page_number = page_number;
|
||||
page_params.document_cookie = params.params.document_cookie;
|
||||
page_params.actual_shrink = actual_shrink;
|
||||
page_params.page_size = page_size_in_dpi;
|
||||
page_params.content_area = content_area_in_dpi;
|
||||
|
||||
if (!CopyMetafileDataToSharedMem(metafile.get(),
|
||||
&(page_params.metafile_data_handle))) {
|
||||
page_params.data_size = 0;
|
||||
}
|
||||
|
||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params));
|
||||
}
|
||||
|
||||
void PrintWebViewHelper::RenderPage(
|
||||
const PrintMsg_Print_Params& params, int page_number, WebFrame* frame,
|
||||
bool is_preview, Metafile* metafile, double* actual_shrink,
|
||||
gfx::Size* page_size_in_dpi, gfx::Rect* content_area_in_dpi) {
|
||||
PageSizeMargins page_layout_in_points;
|
||||
double css_scale_factor = 1.0f;
|
||||
ComputePageLayoutInPointsForCss(frame, page_number, params,
|
||||
ignore_css_margins_, &css_scale_factor,
|
||||
&page_layout_in_points);
|
||||
gfx::Size page_size;
|
||||
gfx::Rect content_area;
|
||||
GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, &page_size,
|
||||
&content_area);
|
||||
int dpi = static_cast<int>(params.dpi);
|
||||
// Calculate the actual page size and content area in dpi.
|
||||
if (page_size_in_dpi) {
|
||||
*page_size_in_dpi = gfx::Size(
|
||||
static_cast<int>(ConvertUnitDouble(page_size.width(), kPointsPerInch,
|
||||
dpi)),
|
||||
static_cast<int>(ConvertUnitDouble(page_size.height(), kPointsPerInch,
|
||||
dpi)));
|
||||
}
|
||||
|
||||
if (content_area_in_dpi) {
|
||||
*content_area_in_dpi = gfx::Rect(
|
||||
static_cast<int>(ConvertUnitDouble(content_area.x(), kPointsPerInch,
|
||||
dpi)),
|
||||
static_cast<int>(ConvertUnitDouble(content_area.y(), kPointsPerInch,
|
||||
dpi)),
|
||||
static_cast<int>(ConvertUnitDouble(content_area.width(), kPointsPerInch,
|
||||
dpi)),
|
||||
static_cast<int>(ConvertUnitDouble(content_area.height(),
|
||||
kPointsPerInch, dpi)));
|
||||
}
|
||||
|
||||
float webkit_page_shrink_factor = frame->getPrintPageShrink(page_number);
|
||||
float scale_factor = css_scale_factor * webkit_page_shrink_factor;
|
||||
|
||||
gfx::Rect canvas_area = content_area;
|
||||
|
||||
SkBaseDevice* device = metafile->StartPageForVectorCanvas(
|
||||
page_size, canvas_area, scale_factor);
|
||||
DCHECK(device);
|
||||
// The printPage method may take a reference to the canvas we pass down, so it
|
||||
// can't be a stack object.
|
||||
skia::RefPtr<skia::VectorCanvas> canvas =
|
||||
skia::AdoptRef(new skia::VectorCanvas(device));
|
||||
|
||||
float webkit_scale_factor = RenderPageContent(frame, page_number, canvas_area,
|
||||
content_area, scale_factor,
|
||||
canvas.get());
|
||||
|
||||
if (*actual_shrink <= 0 || webkit_scale_factor <= 0) {
|
||||
NOTREACHED() << "Printing page " << page_number << " failed.";
|
||||
} else {
|
||||
// While rendering certain plugins (PDF) to metafile, we might need to
|
||||
// set custom scale factor. Update |actual_shrink| with custom scale
|
||||
// if it is set on canvas.
|
||||
// TODO(gene): We should revisit this solution for the next versions.
|
||||
// Consider creating metafile of the right size (or resizable)
|
||||
// https://code.google.com/p/chromium/issues/detail?id=126037
|
||||
if (!MetafileSkiaWrapper::GetCustomScaleOnCanvas(
|
||||
*canvas, actual_shrink)) {
|
||||
// Update the dpi adjustment with the "page |actual_shrink|" calculated in
|
||||
// webkit.
|
||||
*actual_shrink /= (webkit_scale_factor * css_scale_factor);
|
||||
}
|
||||
}
|
||||
|
||||
bool result = metafile->FinishPage();
|
||||
DCHECK(result);
|
||||
}
|
||||
|
||||
bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
|
||||
Metafile* metafile, base::SharedMemoryHandle* shared_mem_handle) {
|
||||
uint32 buf_size = metafile->GetDataSize();
|
||||
base::SharedMemory shared_buf;
|
||||
if (buf_size >= kMetafileMaxSize) {
|
||||
NOTREACHED() << "Buffer too large: " << buf_size;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate a shared memory buffer to hold the generated metafile data.
|
||||
if (!shared_buf.CreateAndMapAnonymous(buf_size)) {
|
||||
NOTREACHED() << "Buffer allocation failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the bits into shared memory.
|
||||
if (!metafile->GetData(shared_buf.memory(), buf_size)) {
|
||||
NOTREACHED() << "GetData() failed";
|
||||
shared_buf.Unmap();
|
||||
return false;
|
||||
}
|
||||
shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle);
|
||||
shared_buf.Unmap();
|
||||
|
||||
Send(new PrintHostMsg_DuplicateSection(routing_id(), *shared_mem_handle,
|
||||
shared_mem_handle));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace printing
|
0
chromium_src/grit/generated_resources.h
Normal file
0
chromium_src/grit/generated_resources.h
Normal file
|
@ -338,7 +338,7 @@ Changes the title of native window to `title`.
|
|||
Returns the title of the native window.
|
||||
|
||||
**Note:** The title of web page can be different from the title of the native
|
||||
**window.
|
||||
window.
|
||||
|
||||
### BrowserWindow.flashFrame()
|
||||
|
||||
|
@ -408,10 +408,10 @@ Starts inspecting element at position (`x`, `y`).
|
|||
### BrowserWindow.capturePage([rect, ]callback)
|
||||
|
||||
* `rect` Object - The area of page to be captured
|
||||
* `x`
|
||||
* `y`
|
||||
* `width`
|
||||
* `height`
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
* `callback` Function
|
||||
|
||||
Captures the snapshot of page within `rect`, upon completion `callback` would be
|
||||
|
@ -426,6 +426,19 @@ encode it and use data URL to embed the image in HTML.
|
|||
[remote](remote.md) if you are going to use this API in renderer
|
||||
process.
|
||||
|
||||
### BrowserWindow.print([options])
|
||||
|
||||
* `options` Object
|
||||
* `silent` Boolean - Don't ask user for print settings, defaults to `false`
|
||||
* `printBackground` Boolean - Also prints the background color and image of
|
||||
the web page, defaults to `false`.
|
||||
|
||||
Prints window's web page. When `silent` is set to `false`, atom-shell will pick
|
||||
up system's default printer and default settings for printing.
|
||||
|
||||
Calling `window.print()` in web page is equivalent to call
|
||||
`BrowserWindow.print({silent: false, printBackground: false})`.
|
||||
|
||||
### BrowserWindow.loadUrl(url)
|
||||
|
||||
Same with `webContents.loadUrl(url)`.
|
||||
|
|
3
script/cpplint.py
vendored
3
script/cpplint.py
vendored
|
@ -16,10 +16,11 @@ IGNORE_FILES = [
|
|||
os.path.join('atom', 'browser', 'ui', 'cocoa', 'atom_menu_controller.h'),
|
||||
os.path.join('atom', 'browser', 'ui', 'gtk', 'gtk_custom_menu.cc'),
|
||||
os.path.join('atom', 'browser', 'ui', 'gtk', 'gtk_custom_menu_item.cc'),
|
||||
os.path.join('atom', 'common', 'api', 'api_messages.cc'),
|
||||
os.path.join('atom', 'common', 'api', 'api_messages.h'),
|
||||
os.path.join('atom', 'common', 'api', 'atom_extensions.h'),
|
||||
os.path.join('atom', 'common', 'atom_version.h'),
|
||||
os.path.join('atom', 'common', 'common_message_generator.cc'),
|
||||
os.path.join('atom', 'common', 'common_message_generator.h'),
|
||||
os.path.join('atom', 'common', 'swap_or_assign.h'),
|
||||
]
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import sys
|
|||
|
||||
NODE_VERSION = 'v0.11.13'
|
||||
BASE_URL = 'https://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent'
|
||||
LIBCHROMIUMCONTENT_COMMIT = 'bb664e4665851fe923ce904e620ba43d8d010ba5'
|
||||
LIBCHROMIUMCONTENT_COMMIT = '432720d4613e3aac939f127fe55b9d44fea349e5'
|
||||
|
||||
ARCH = {
|
||||
'cygwin': '32bit',
|
||||
|
|
Loading…
Reference in a new issue