No dual_mode on Win10+ shortcuts.
[chromium-blink-merge.git] / chrome / browser / printing / print_dialog_cloud_win.cc
blob1333f7cf9b0fb11c197f005603e612366b2a9732
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/printing/print_dialog_cloud.h"
7 #include "base/base64.h"
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/memory/ref_counted_memory.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_window.h"
20 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "components/cloud_devices/common/cloud_devices_urls.h"
23 #include "components/google/core/browser/google_util.h"
24 #include "content/public/browser/browser_context.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/render_frame_host.h"
28 namespace print_dialog_cloud {
30 namespace {
32 // Limit is used only to allocate memory. Cloud has own small limit.
33 const int kMaxFileSize = 1024 * 1024 * 1024;
35 // Sets print data into Cloud Print widget.
36 class PrintDataSetter : public content::WebContentsObserver {
37 public:
38 PrintDataSetter(content::WebContents* web_contents,
39 const scoped_refptr<base::RefCountedMemory>& data,
40 const base::string16& print_job_title,
41 const base::string16& print_ticket,
42 const std::string& file_type)
43 : WebContentsObserver(web_contents) {
44 DCHECK_NE(data->size(), 0u);
45 std::string base64_data;
46 base::Base64Encode(base::StringPiece(data->front_as<char>(), data->size()),
47 &base64_data);
48 std::string header("data:");
49 header.append(file_type);
50 header.append(";base64,");
51 base64_data.insert(0, header);
53 InitPrintFunction(base::StringValue(base64_data),
54 base::StringValue(print_job_title));
57 private:
58 // Overridden from content::WebContentsObserver:
59 void DocumentLoadedInFrame(
60 content::RenderFrameHost* render_frame_host) override {
61 if (cloud_devices::IsCloudPrintURL(web_contents()->GetURL()))
62 render_frame_host->ExecuteJavaScript(print_function_);
65 void WebContentsDestroyed() override { delete this; }
67 void InitPrintFunction(const base::Value& arg1, const base::Value& arg2) {
68 std::vector<const base::Value*> args;
69 args.push_back(&arg1);
70 args.push_back(&arg2);
71 print_function_ =
72 content::WebUI::GetJavascriptCall("printApp._printDataUrl", args);
75 base::string16 print_function_;
77 DISALLOW_COPY_AND_ASSIGN(PrintDataSetter);
80 void CreatePrintDialog(content::BrowserContext* browser_context,
81 const base::string16& print_job_title,
82 const base::string16& print_ticket,
83 const std::string& file_type,
84 const scoped_refptr<base::RefCountedMemory>& data) {
85 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
86 Profile* profile = Profile::FromBrowserContext(browser_context);
87 chrome::ScopedTabbedBrowserDisplayer displayer(profile,
88 chrome::GetActiveDesktop());
89 GURL url = cloud_devices::GetCloudPrintRelativeURL("client/dialog.html");
90 content::WebContents* web_contents =
91 displayer.browser()->OpenURL(content::OpenURLParams(
92 google_util::AppendGoogleLocaleParam(
93 url, g_browser_process->GetApplicationLocale()),
94 content::Referrer(), NEW_FOREGROUND_TAB,
95 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false));
96 if (data && data->size()) {
97 new PrintDataSetter(web_contents, data, print_job_title, print_ticket,
98 file_type);
102 scoped_refptr<base::RefCountedMemory> ReadFile(
103 const base::FilePath& path_to_file) {
104 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
105 scoped_refptr<base::RefCountedMemory> data;
106 int64_t file_size = 0;
107 if (base::GetFileSize(path_to_file, &file_size) && file_size != 0) {
108 if (file_size > kMaxFileSize) {
109 DLOG(WARNING) << " print data file too large to reserve space";
110 return data;
112 std::string file_data;
113 file_data.reserve(static_cast<size_t>(file_size));
114 if (base::ReadFileToString(path_to_file, &file_data))
115 data = base::RefCountedString::TakeString(&file_data);
117 base::DeleteFile(path_to_file, false);
118 return data;
121 void CreatePrintDialogForFile(content::BrowserContext* browser_context,
122 const base::FilePath& path_to_file,
123 const base::string16& print_job_title,
124 const base::string16& print_ticket,
125 const std::string& file_type) {
126 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
127 content::BrowserThread::PostTaskAndReplyWithResult(
128 content::BrowserThread::FILE, FROM_HERE,
129 base::Bind(&ReadFile, path_to_file),
130 base::Bind(&CreatePrintDialog, browser_context,
131 print_job_title, print_ticket, file_type));
134 } // namespace
136 bool CreatePrintDialogFromCommandLine(Profile* profile,
137 const base::CommandLine& command_line) {
138 base::FilePath cloud_print_file =
139 command_line.GetSwitchValuePath(switches::kCloudPrintFile);
140 DCHECK(!cloud_print_file.empty());
141 if (cloud_print_file.empty())
142 return false;
143 base::string16 print_job_title =
144 command_line.GetSwitchValueNative(switches::kCloudPrintJobTitle);
145 base::string16 print_job_print_ticket =
146 command_line.GetSwitchValueNative(switches::kCloudPrintPrintTicket);
147 std::string file_type =
148 command_line.GetSwitchValueASCII(switches::kCloudPrintFileType);
149 if (file_type.empty())
150 file_type = "application/pdf";
151 CreatePrintDialogForFile(profile, cloud_print_file, print_job_title,
152 print_job_print_ticket, file_type);
153 return true;
156 } // namespace print_dialog_cloud