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)
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/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_tabstrip.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/ui/scoped_tabbed_browser_displayer.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()) {
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (it->GetLastCommittedURL() == 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)
750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!ActivateAndGetBrowserForUrl(url)) {
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    chrome::ScopedTabbedBrowserDisplayer displayer(
770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        profile, chrome::HOST_DESKTOP_TYPE_ASH);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent",
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              PAGE_DISPLAYED, PRINTER_SERVICE_EVENT_MAX);
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    chrome::AddSelectedTabWithURL(displayer.browser(), url,
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  ui::PAGE_TRANSITION_LINK);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrinterServiceProvider::PrinterServiceProvider()
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : weak_ptr_factory_(this) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrinterServiceProvider::~PrinterServiceProvider() {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrinterServiceProvider::Start(
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<dbus::ExportedObject> exported_object) {
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_ = exported_object;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "PrinterServiceProvider started";
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exported_object_->ExportMethod(
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kLibCrosServiceInterface,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kPrinterAdded,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PrinterServiceProvider::PrinterAdded,
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()),
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PrinterServiceProvider::OnExported,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrinterServiceProvider::OnExported(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& interface_name,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& method_name,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success) {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!success) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Failed to export " << interface_name << "."
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << method_name;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Method exported: " << interface_name << "." << method_name;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrinterServiceProvider::ShowCloudPrintHelp(const std::string& vendor,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                const std::string& product) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::Bind(&FindOrOpenCloudPrintPage, vendor,
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              product));
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrinterServiceProvider::PrinterAdded(
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MethodCall* method_call,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::ExportedObject::ResponseSender response_sender) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "PrinterAdded " << method_call->ToString();
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dbus::MessageReader reader(method_call);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string vendor;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string product;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't check for error, parameters are optional. If some string is empty
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // web server will show generic help page.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  reader.PopString(&vendor);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  reader.PopString(&product);
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShowCloudPrintHelp(vendor, product);
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send an empty response.
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_sender.Run(dbus::Response::FromMethodCall(method_call));
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
148