printer_service_provider.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/dbus/printer_service_provider.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/session_state_delegate.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/window_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/bus.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/exported_object.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/message.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/escape.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kPrinterAdded[] = "PrinterAdded";
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)enum PrinterServiceEvent {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PRINTER_ADDED,
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PAGE_DISPLAYED,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PRINTER_SERVICE_EVENT_MAX,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(vitalybuka): update URL with more relevant information.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kCloudPrintLearnUrl[] =
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "https://www.google.com/landing/cloudprint/index.html";
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ActivateContents(Browser* browser, content::WebContents* contents) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser->tab_strip_model()->ActivateTabAt(
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetIndexOfWebContents(contents), false);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Browser* ActivateAndGetBrowserForUrl(GURL url) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (TabContentsIterator it; !it.done(); it.Next()) {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->GetURL() == url) {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ActivateContents(it.browser(), *it);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return it.browser();
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FindOrOpenCloudPrintPage(const std::string& /* vendor */,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const std::string& /* product */) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", PRINTER_ADDED,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            PRINTER_SERVICE_EVENT_MAX);
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!ash::Shell::GetInstance()->session_state_delegate()->
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          IsActiveUserSessionStarted() ||
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ash::Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile = ProfileManager::GetLastUsedProfile();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!profile)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url(kCloudPrintLearnUrl);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Browser* browser = ActivateAndGetBrowserForUrl(url);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!browser) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser = chrome::FindOrCreateTabbedBrowser(profile,
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                chrome::HOST_DESKTOP_TYPE_ASH);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!browser)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent",
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              PAGE_DISPLAYED, PRINTER_SERVICE_EVENT_MAX);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome::AddSelectedTabWithURL(browser, url,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  content::PAGE_TRANSITION_LINK);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* window = browser->window()->GetNativeWindow();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (window) {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window->Show();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ash::wm::ActivateWindow(window);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrinterServiceProvider::PrinterServiceProvider()
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : weak_ptr_factory_(this) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrinterServiceProvider::~PrinterServiceProvider() {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrinterServiceProvider::Start(
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<dbus::ExportedObject> exported_object) {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_ = exported_object;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "PrinterServiceProvider started";
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_->ExportMethod(
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kLibCrosServiceInterface,
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kPrinterAdded,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PrinterServiceProvider::PrinterAdded,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()),
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PrinterServiceProvider::OnExported,
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrinterServiceProvider::OnExported(
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& interface_name,
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& method_name,
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!success) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Failed to export " << interface_name << "."
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << method_name;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Method exported: " << interface_name << "." << method_name;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrinterServiceProvider::ShowCloudPrintHelp(const std::string& vendor,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                const std::string& product) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::Bind(&FindOrOpenCloudPrintPage, vendor,
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              product));
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrinterServiceProvider::PrinterAdded(
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MethodCall* method_call,
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::ExportedObject::ResponseSender response_sender) {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "PrinterAdded " << method_call->ToString();
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dbus::MessageReader reader(method_call);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string vendor;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string product;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't check for error, parameters are optional. If some string is empty
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // web server will show generic help page.
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  reader.PopString(&vendor);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  reader.PopString(&product);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShowCloudPrintHelp(vendor, product);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send an empty response.
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(dbus::Response::FromMethodCall(method_call));
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
156