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/session_state_delegate.h" 8#include "ash/shell.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 "chrome/browser/profiles/profile_manager.h" 15#include "chrome/browser/ui/browser.h" 16#include "chrome/browser/ui/browser_tabstrip.h" 17#include "chrome/browser/ui/browser_window.h" 18#include "chrome/browser/ui/scoped_tabbed_browser_displayer.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->GetLastCommittedURL() == 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()->session_state_delegate()-> 64 IsActiveUserSessionStarted() || 65 ash::Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) { 66 return; 67 } 68 69 Profile* profile = ProfileManager::GetLastUsedProfile(); 70 if (!profile) 71 return; 72 73 GURL url(kCloudPrintLearnUrl); 74 75 if (!ActivateAndGetBrowserForUrl(url)) { 76 chrome::ScopedTabbedBrowserDisplayer displayer( 77 profile, chrome::HOST_DESKTOP_TYPE_ASH); 78 UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", 79 PAGE_DISPLAYED, PRINTER_SERVICE_EVENT_MAX); 80 chrome::AddSelectedTabWithURL(displayer.browser(), url, 81 content::PAGE_TRANSITION_LINK); 82 } 83} 84 85} // namespace 86 87namespace chromeos { 88 89PrinterServiceProvider::PrinterServiceProvider() 90 : weak_ptr_factory_(this) { 91} 92 93PrinterServiceProvider::~PrinterServiceProvider() { 94} 95 96void PrinterServiceProvider::Start( 97 scoped_refptr<dbus::ExportedObject> exported_object) { 98 99 exported_object_ = exported_object; 100 DVLOG(1) << "PrinterServiceProvider started"; 101 exported_object_->ExportMethod( 102 kLibCrosServiceInterface, 103 kPrinterAdded, 104 base::Bind(&PrinterServiceProvider::PrinterAdded, 105 weak_ptr_factory_.GetWeakPtr()), 106 base::Bind(&PrinterServiceProvider::OnExported, 107 weak_ptr_factory_.GetWeakPtr())); 108} 109 110void PrinterServiceProvider::OnExported( 111 const std::string& interface_name, 112 const std::string& method_name, 113 bool success) { 114 if (!success) { 115 LOG(ERROR) << "Failed to export " << interface_name << "." 116 << method_name; 117 } 118 DVLOG(1) << "Method exported: " << interface_name << "." << method_name; 119} 120 121void PrinterServiceProvider::ShowCloudPrintHelp(const std::string& vendor, 122 const std::string& product) { 123 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 124 base::Bind(&FindOrOpenCloudPrintPage, vendor, 125 product)); 126} 127 128void PrinterServiceProvider::PrinterAdded( 129 dbus::MethodCall* method_call, 130 dbus::ExportedObject::ResponseSender response_sender) { 131 DVLOG(1) << "PrinterAdded " << method_call->ToString(); 132 133 dbus::MessageReader reader(method_call); 134 std::string vendor; 135 std::string product; 136 // Don't check for error, parameters are optional. If some string is empty 137 // web server will show generic help page. 138 reader.PopString(&vendor); 139 reader.PopString(&product); 140 ShowCloudPrintHelp(vendor, product); 141 142 // Send an empty response. 143 response_sender.Run(dbus::Response::FromMethodCall(method_call)); 144} 145 146} // namespace chromeos 147 148