1 // Copyright (c) 2012 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/chromeos/dbus/printer_service_provider.h"
7 #include "ash/session/session_state_delegate.h"
9 #include "ash/wm/window_util.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/metrics/histogram.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/sys_info.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_tabstrip.h"
18 #include "chrome/browser/ui/browser_window.h"
19 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
20 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_version_info.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/web_contents.h"
26 #include "dbus/exported_object.h"
27 #include "dbus/message.h"
28 #include "net/base/escape.h"
29 #include "third_party/cros_system_api/dbus/service_constants.h"
30 #include "ui/aura/window.h"
34 const char kPrinterAdded
[] = "PrinterAdded";
36 enum PrinterServiceEvent
{
39 PRINTER_SERVICE_EVENT_MAX
,
42 // TODO(vitalybuka): update URL with more relevant information.
43 const char kCloudPrintLearnUrl
[] =
44 "https://www.google.com/landing/cloudprint/index.html";
46 void ActivateContents(Browser
* browser
, content::WebContents
* contents
) {
47 browser
->tab_strip_model()->ActivateTabAt(
48 browser
->tab_strip_model()->GetIndexOfWebContents(contents
), false);
51 Browser
* ActivateAndGetBrowserForUrl(GURL url
) {
52 for (TabContentsIterator it
; !it
.done(); it
.Next()) {
53 if (it
->GetLastCommittedURL() == url
) {
54 ActivateContents(it
.browser(), *it
);
61 void FindOrOpenCloudPrintPage(const std::string
& /* vendor */,
62 const std::string
& /* product */) {
63 UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", PRINTER_ADDED
,
64 PRINTER_SERVICE_EVENT_MAX
);
65 if (!ash::Shell::GetInstance()->session_state_delegate()->
66 IsActiveUserSessionStarted() ||
67 ash::Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) {
71 Profile
* profile
= ProfileManager::GetLastUsedProfile();
75 GURL
url(kCloudPrintLearnUrl
);
77 if (!ActivateAndGetBrowserForUrl(url
)) {
78 chrome::ScopedTabbedBrowserDisplayer
displayer(
79 profile
, chrome::HOST_DESKTOP_TYPE_ASH
);
80 UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent",
81 PAGE_DISPLAYED
, PRINTER_SERVICE_EVENT_MAX
);
82 chrome::AddSelectedTabWithURL(displayer
.browser(), url
,
83 ui::PAGE_TRANSITION_LINK
);
91 PrinterServiceProvider::PrinterServiceProvider()
92 : weak_ptr_factory_(this) {
95 PrinterServiceProvider::~PrinterServiceProvider() {
98 void PrinterServiceProvider::Start(
99 scoped_refptr
<dbus::ExportedObject
> exported_object
) {
100 exported_object_
= exported_object
;
102 DVLOG(1) << "PrinterServiceProvider started";
103 exported_object_
->ExportMethod(
104 kLibCrosServiceInterface
,
106 base::Bind(&PrinterServiceProvider::PrinterAdded
,
107 weak_ptr_factory_
.GetWeakPtr()),
108 base::Bind(&PrinterServiceProvider::OnExported
,
109 weak_ptr_factory_
.GetWeakPtr()));
112 void PrinterServiceProvider::OnExported(
113 const std::string
& interface_name
,
114 const std::string
& method_name
,
117 LOG(ERROR
) << "Failed to export " << interface_name
<< "."
120 DVLOG(1) << "Method exported: " << interface_name
<< "." << method_name
;
123 void PrinterServiceProvider::ShowCloudPrintHelp(const std::string
& vendor
,
124 const std::string
& product
) {
125 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
126 base::Bind(&FindOrOpenCloudPrintPage
, vendor
,
130 void PrinterServiceProvider::PrinterAdded(
131 dbus::MethodCall
* method_call
,
132 dbus::ExportedObject::ResponseSender response_sender
) {
133 DVLOG(1) << "PrinterAdded " << method_call
->ToString();
135 // Disable showing Cloudprint help on canary and dev channel, as these have
136 // support for printerProvider API.
137 // TODO(tbarzic): Remove this and offer the user to search for an extension
138 // that can act as a print driver (using printerProvider API) for USB printers
139 // detected by this service. http://crbug.com/439448
140 if (base::SysInfo::IsRunningOnChromeOS() &&
141 chrome::VersionInfo::GetChannel() <= chrome::VersionInfo::CHANNEL_DEV
)
144 dbus::MessageReader
reader(method_call
);
147 // Don't check for error, parameters are optional. If some string is empty
148 // web server will show generic help page.
149 reader
.PopString(&vendor
);
150 reader
.PopString(&product
);
151 ShowCloudPrintHelp(vendor
, product
);
153 // Send an empty response.
154 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
157 } // namespace chromeos