printer_service_provider.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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.
4
5#include "chrome/browser/chromeos/dbus/printer_service_provider.h"
6
7#include "ash/shell.h"
8#include "ash/shell_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/stringprintf.h"
14#include "chrome/browser/profiles/profile_manager.h"
15#include "chrome/browser/ui/browser.h"
16#include "chrome/browser/ui/browser_finder.h"
17#include "chrome/browser/ui/browser_tabstrip.h"
18#include "chrome/browser/ui/browser_window.h"
19#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
20#include "chrome/browser/ui/tabs/tab_strip_model.h"
21#include "content/public/browser/browser_thread.h"
22#include "content/public/browser/web_contents.h"
23#include "dbus/bus.h"
24#include "dbus/exported_object.h"
25#include "dbus/message.h"
26#include "net/base/escape.h"
27#include "third_party/cros_system_api/dbus/service_constants.h"
28#include "ui/aura/window.h"
29
30namespace {
31
32const char kPrinterAdded[] = "PrinterAdded";
33
34enum PrinterServiceEvent {
35  PRINTER_ADDED,
36  PAGE_DISPLAYED,
37  PRINTER_SERVICE_EVENT_MAX,
38};
39
40// TODO(vitalybuka): update URL with more relevant information.
41const char kCloudPrintLearnUrl[] =
42    "https://www.google.com/landing/cloudprint/index.html";
43
44void ActivateContents(Browser* browser, content::WebContents* contents) {
45  browser->tab_strip_model()->ActivateTabAt(
46      browser->tab_strip_model()->GetIndexOfWebContents(contents), false);
47}
48
49Browser* ActivateAndGetBrowserForUrl(GURL url) {
50  for (TabContentsIterator it; !it.done(); it.Next()) {
51    if (it->GetURL() == url) {
52      ActivateContents(it.browser(), *it);
53      return it.browser();
54    }
55  }
56  return NULL;
57}
58
59void FindOrOpenCloudPrintPage(const std::string& /* vendor */,
60                              const std::string& /* product */) {
61  UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", PRINTER_ADDED,
62                            PRINTER_SERVICE_EVENT_MAX);
63  if (!ash::Shell::GetInstance()->delegate()->IsSessionStarted() ||
64      ash::Shell::GetInstance()->delegate()->IsScreenLocked()) {
65    return;
66  }
67
68  Profile* profile = ProfileManager::GetLastUsedProfile();
69  if (!profile)
70    return;
71
72  GURL url(kCloudPrintLearnUrl);
73
74  Browser* browser = ActivateAndGetBrowserForUrl(url);
75  if (!browser) {
76    browser = chrome::FindOrCreateTabbedBrowser(profile,
77                                                chrome::HOST_DESKTOP_TYPE_ASH);
78    if (!browser)
79      return;
80    UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent",
81                              PAGE_DISPLAYED, PRINTER_SERVICE_EVENT_MAX);
82    chrome::AddSelectedTabWithURL(browser, url,
83                                  content::PAGE_TRANSITION_LINK);
84  }
85  aura::Window* window = browser->window()->GetNativeWindow();
86  if (window) {
87    window->Show();
88    ash::wm::ActivateWindow(window);
89  }
90}
91
92}  // namespace
93
94namespace chromeos {
95
96PrinterServiceProvider::PrinterServiceProvider()
97    : weak_ptr_factory_(this) {
98}
99
100PrinterServiceProvider::~PrinterServiceProvider() {
101}
102
103void PrinterServiceProvider::Start(
104    scoped_refptr<dbus::ExportedObject> exported_object) {
105
106  exported_object_ = exported_object;
107  DVLOG(1) << "PrinterServiceProvider started";
108  exported_object_->ExportMethod(
109      kLibCrosServiceInterface,
110      kPrinterAdded,
111      base::Bind(&PrinterServiceProvider::PrinterAdded,
112                 weak_ptr_factory_.GetWeakPtr()),
113      base::Bind(&PrinterServiceProvider::OnExported,
114                 weak_ptr_factory_.GetWeakPtr()));
115}
116
117void PrinterServiceProvider::OnExported(
118    const std::string& interface_name,
119    const std::string& method_name,
120    bool success) {
121  if (!success) {
122    LOG(ERROR) << "Failed to export " << interface_name << "."
123               << method_name;
124  }
125  DVLOG(1) << "Method exported: " << interface_name << "." << method_name;
126}
127
128void PrinterServiceProvider::ShowCloudPrintHelp(const std::string& vendor,
129                                                const std::string& product) {
130  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
131                                   base::Bind(&FindOrOpenCloudPrintPage, vendor,
132                                              product));
133}
134
135void PrinterServiceProvider::PrinterAdded(
136    dbus::MethodCall* method_call,
137    dbus::ExportedObject::ResponseSender response_sender) {
138  DVLOG(1) << "PrinterAdded " << method_call->ToString();
139
140  dbus::MessageReader reader(method_call);
141  std::string vendor;
142  std::string product;
143  // Don't check for error, parameters are optional. If some string is empty
144  // web server will show generic help page.
145  reader.PopString(&vendor);
146  reader.PopString(&product);
147  ShowCloudPrintHelp(vendor, product);
148
149  // Send an empty response.
150  response_sender.Run(dbus::Response::FromMethodCall(method_call));
151}
152
153}  // namespace chromeos
154
155