diff options
author | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-08 08:38:21 +0000 |
---|---|---|
committer | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-08 08:38:21 +0000 |
commit | dede536dcf979440617949aca1dc81abd69db700 (patch) | |
tree | 0abe92a258342ad4607504df3efdc971897a5475 /chrome/browser/chromeos/dbus | |
parent | 58078bd1dd756f4d29a28e7632e7f66dadf2aa7a (diff) | |
download | chromium_src-dede536dcf979440617949aca1dc81abd69db700.zip chromium_src-dede536dcf979440617949aca1dc81abd69db700.tar.gz chromium_src-dede536dcf979440617949aca1dc81abd69db700.tar.bz2 |
D-Bus service to show cloud print help page.
Method will be called by udev rule on Chrome OS.
BUG=chromium-os:36376
Review URL: https://chromiumcodereview.appspot.com/11412261
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171961 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/dbus')
4 files changed, 294 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/dbus/cros_dbus_service.cc b/chrome/browser/chromeos/dbus/cros_dbus_service.cc index 35586ae..a6f8b63 100644 --- a/chrome/browser/chromeos/dbus/cros_dbus_service.cc +++ b/chrome/browser/chromeos/dbus/cros_dbus_service.cc @@ -9,6 +9,7 @@ #include "base/stl_util.h" #include "base/threading/platform_thread.h" #include "chrome/browser/chromeos/dbus/liveness_service_provider.h" +#include "chrome/browser/chromeos/dbus/printer_service_provider.h" #include "chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "dbus/bus.h" @@ -111,6 +112,7 @@ void CrosDBusService::Initialize() { CrosDBusServiceImpl* service = new CrosDBusServiceImpl(bus); service->RegisterServiceProvider(ProxyResolutionServiceProvider::Create()); service->RegisterServiceProvider(new LivenessServiceProvider); + service->RegisterServiceProvider(new PrinterServiceProvider); g_cros_dbus_service = service; service->Start(); } else { diff --git a/chrome/browser/chromeos/dbus/printer_service_provider.cc b/chrome/browser/chromeos/dbus/printer_service_provider.cc new file mode 100644 index 0000000..981558a --- /dev/null +++ b/chrome/browser/chromeos/dbus/printer_service_provider.cc @@ -0,0 +1,156 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/dbus/printer_service_provider.h" + +#include "ash/wm/window_util.h" +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/metrics/histogram.h" +#include "base/stringprintf.h" +#include "chrome/browser/chromeos/login/user_manager.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/tab_contents/tab_contents.h" +#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" +#include "dbus/bus.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "net/base/escape.h" +#include "third_party/cros_system_api/dbus/service_constants.h" +#include "ui/aura/window.h" + +namespace { + +const char kPrinterAdded[] = "PrinterAdded"; + +enum PrinterServiceEvent { + PRINTER_ADDED, + PAGE_DISPLAYED, + PRINTER_SERVICE_EVENT_MAX, +}; + +// TODO(vitalybuka): update URL with more relevant information. +const char kCloudPrintLearnUrl[] = + "http://www.google.com/landing/cloudprint/index.html?vendor=%s&product=%s"; + +void ActivateContents(Browser* browser, content::WebContents* contents) { + browser->tab_strip_model()->ActivateTabAt( + browser->tab_strip_model()->GetIndexOfWebContents(contents), false); +} + +Browser* ActivateAndGetBrowserForUrl(GURL url) { + for (TabContentsIterator it; !it.done(); ++it) { + if (it->GetURL() == url) { + ActivateContents(it.browser(), *it); + return it.browser(); + } + } + return NULL; +} + +void FindOrOpenCloudPrintPage(const std::string& vendor, + const std::string& product) { + UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", PRINTER_ADDED, + PRINTER_SERVICE_EVENT_MAX); + if (!chromeos::UserManager::Get()->IsUserLoggedIn()) + return; + + Profile* profile = ProfileManager::GetLastUsedProfile(); + if (!profile) + return; + + // Escape param just in case. Usually vendor and model should be just integer. + GURL url( + base::StringPrintf(kCloudPrintLearnUrl, + net::EscapeQueryParamValue(vendor, true).c_str(), + net::EscapeQueryParamValue(product, true).c_str())); + + Browser* browser = ActivateAndGetBrowserForUrl(url); + if (!browser) { + browser = browser::FindOrCreateTabbedBrowser(profile, + chrome::HOST_DESKTOP_TYPE_ASH); + if (!browser) + return; + UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", + PAGE_DISPLAYED, PRINTER_SERVICE_EVENT_MAX); + chrome::AddSelectedTabWithURL(browser, url, + content::PAGE_TRANSITION_LINK); + } + aura::Window* window = browser->window()->GetNativeWindow(); + if (window) { + window->Show(); + ash::wm::ActivateWindow(window); + } +} + +} // namespace + +namespace chromeos { + +PrinterServiceProvider::PrinterServiceProvider() + : weak_ptr_factory_(this) { +} + +PrinterServiceProvider::~PrinterServiceProvider() { +} + +void PrinterServiceProvider::Start( + scoped_refptr<dbus::ExportedObject> exported_object) { + + exported_object_ = exported_object; + DVLOG(1) << "PrinterServiceProvider started"; + exported_object_->ExportMethod( + kLibCrosServiceInterface, + kPrinterAdded, + base::Bind(&PrinterServiceProvider::PrinterAdded, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&PrinterServiceProvider::OnExported, + weak_ptr_factory_.GetWeakPtr())); +} + +void PrinterServiceProvider::OnExported( + const std::string& interface_name, + const std::string& method_name, + bool success) { + if (!success) { + LOG(ERROR) << "Failed to export " << interface_name << "." + << method_name; + } + DVLOG(1) << "Method exported: " << interface_name << "." << method_name; +} + +void PrinterServiceProvider::ShowCloudPrintHelp(const std::string& vendor, + const std::string& product) { + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&FindOrOpenCloudPrintPage, vendor, + product)); +} + +void PrinterServiceProvider::PrinterAdded( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DVLOG(1) << "PrinterAdded " << method_call->ToString(); + + dbus::MessageReader reader(method_call); + std::string vendor; + std::string product; + // Don't check for error, parameters are optional. If some string is empty + // web server will show generic help page. + reader.PopString(&vendor); + reader.PopString(&product); + ShowCloudPrintHelp(vendor, product); + + // Send an empty response. + response_sender.Run(dbus::Response::FromMethodCall(method_call)); +} + +} // namespace chromeos + diff --git a/chrome/browser/chromeos/dbus/printer_service_provider.h b/chrome/browser/chromeos/dbus/printer_service_provider.h new file mode 100644 index 0000000..42381be --- /dev/null +++ b/chrome/browser/chromeos/dbus/printer_service_provider.h @@ -0,0 +1,81 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_DBUS_PRINTER_SERVICE_PROVIDER_H_ +#define CHROME_BROWSER_CHROMEOS_DBUS_PRINTER_SERVICE_PROVIDER_H_ + +#include <string> + +#include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" +#include "dbus/exported_object.h" + +namespace dbus { +class MethodCall; +class Response; +} + +namespace chromeos { + +// This class provides printer service for CrosDBusService. +// It detects attached printers and show user help page. +// +// The following methods are exported. +// +// Interface: org.chromium.LibCrosServiceInterface (kLibCrosServiceInterface) +// Method: PrinterAdded (kPrinterAdded) +// Parameters: string:vendor Optional, USB vendor ID. +// string:product Optional, USB product ID. +// +// Display help page to advice user to use Cloud Print. +// +// The returned signal will contain the three values: +// +// This service can be manually tested dbus-send on ChromeOS. +// +// 1. Open a terminal and run the following: +// +// % dbus-send --system --type=method_call +// --dest=org.chromium.LibCrosService /org/chromium/LibCrosService +// org.chromium.LibCrosServiceInterface.PrinterAdded +// string:123 string:456 +// +// 2. Go back to ChromeOS and check if new tab with information is opened. + +class PrinterServiceProvider + : public CrosDBusService::ServiceProviderInterface { + public: + PrinterServiceProvider(); + virtual ~PrinterServiceProvider(); + + // CrosDBusService::ServiceProviderInterface override. + virtual void Start( + scoped_refptr<dbus::ExportedObject> exported_object) OVERRIDE; + + protected: + virtual void ShowCloudPrintHelp(const std::string& vendor, + const std::string& product); + + private: + // Called from ExportedObject, when PrinterAdded() is exported as + // a D-Bus method, or failed to be exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success); + + // Invoked when usb printer is detected. + // Called on UI thread from dbus request. + void PrinterAdded(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender); + + scoped_refptr<dbus::ExportedObject> exported_object_; + base::WeakPtrFactory<PrinterServiceProvider> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PrinterServiceProvider); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_DBUS_PRINTER_SERVICE_PROVIDER_H_ + diff --git a/chrome/browser/chromeos/dbus/printer_service_provider_unittest.cc b/chrome/browser/chromeos/dbus/printer_service_provider_unittest.cc new file mode 100644 index 0000000..b21e7ec --- /dev/null +++ b/chrome/browser/chromeos/dbus/printer_service_provider_unittest.cc @@ -0,0 +1,55 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/dbus/printer_service_provider.h" + +#include "chrome/browser/chromeos/dbus/service_provider_test_helper.h" +#include "dbus/message.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { + +const char kPrinterAdded[] = "PrinterAdded"; + +class MockPrinterServiceProvider : public PrinterServiceProvider { + public: + MOCK_METHOD2(ShowCloudPrintHelp, + void(const std::string& vendor, const std::string& product)); +}; + +class PrinterServiceProviderTest : public testing::Test { + public: + virtual void SetUp() OVERRIDE { + test_helper_.SetUp(kPrinterAdded, &service_provider_); + } + + virtual void TearDown() OVERRIDE { + test_helper_.TearDown(); + } + + protected: + MockPrinterServiceProvider service_provider_; + ServiceProviderTestHelper test_helper_; +}; + +TEST_F(PrinterServiceProviderTest, ShowCloudPrintHelp) { + dbus::MethodCall method_call(kLibCrosServiceInterface, kPrinterAdded); + dbus::MessageWriter writer(&method_call); + writer.AppendString("123"); + writer.AppendString("456"); + + EXPECT_CALL(service_provider_, ShowCloudPrintHelp("123", "456")) + .Times(1); + + // Call the PrinterAdded method. + scoped_ptr<dbus::Response> response(test_helper_.CallMethod(&method_call)); + + // An empty response should be returned. + ASSERT_TRUE(response.get()); + dbus::MessageReader reader(response.get()); + ASSERT_FALSE(reader.HasMoreData()); +} + +} // namespace chromeos + |