cloud_print_proxy_backend.cc revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/cloud_print/cloud_print_proxy_backend.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/cloud_print/cloud_print_constants.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/cloud_print/cloud_print_auth.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/cloud_print/cloud_print_connector.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/cloud_print/cloud_print_helpers.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/cloud_print/cloud_print_token_store.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/cloud_print/connector_settings.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/gaia/service_gaia_authenticator.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/net/service_url_request_context.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/service_process.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_oauth_client.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/notifier/base/notifier_options.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/notifier/listener/push_client.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/notifier/listener/push_client_observer.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cloud_print { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The real guts of CloudPrintProxyBackend, to keep the public client API clean. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintProxyBackend::Core 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCountedThreadSafe<CloudPrintProxyBackend::Core>, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public CloudPrintAuth::Client, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public CloudPrintConnector::Client, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public notifier::PushClientObserver { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It is OK for print_server_url to be empty. In this case system should 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use system default (local) print server. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Core(CloudPrintProxyBackend* backend, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ConnectorSettings& settings, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gaia::OAuthClientInfo& oauth_client_info, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_job_poll); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The Do* methods are the various entry points from CloudPrintProxyBackend 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It calls us on a dedicated thread to actually perform synchronous 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (and potentially blocking) operations. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called on the CloudPrintProxyBackend core_thread_ to perform 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialization. When we are passed in an LSID we authenticate using that 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and retrieve new auth tokens. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoInitializeWithLsid(const std::string& lsid, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_robot_refresh_token, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_robot_email, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_user_email); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoInitializeWithToken(const std::string& cloud_print_token); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoInitializeWithRobotToken(const std::string& robot_oauth_refresh_token, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoInitializeWithRobotAuthCode(const std::string& robot_oauth_auth_code, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called on the CloudPrintProxyBackend core_thread_ to perform 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shutdown. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoShutdown(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoRegisterSelectedPrinters( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const printing::PrinterList& printer_list); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoUnregisterPrinters(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CloudPrintAuth::Client implementation. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnAuthenticationComplete( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& access_token, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_oauth_refresh_token, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_email) OVERRIDE; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnInvalidCredentials() OVERRIDE; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CloudPrintConnector::Client implementation. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnAuthFailed() OVERRIDE; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifier::PushClientObserver implementation. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnNotificationsEnabled() OVERRIDE; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnNotificationsDisabled( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier::NotificationsDisabledReason reason) OVERRIDE; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnIncomingNotification( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const notifier::Notification& notification) OVERRIDE; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnPingResponse() OVERRIDE; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<Core>; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Core() {} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateAuthAndConnector(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DestroyAuthAndConnector(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NotifyXXX is how the Core communicates with the frontend across 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // threads. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyPrinterListAvailable( 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const printing::PrinterList& printer_list); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyAuthenticated( 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_oauth_refresh_token, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_email); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyAuthenticationFailed(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyPrintSystemUnavailable(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyUnregisterPrinters(const std::string& auth_token, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::list<std::string>& printer_ids); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Init XMPP channel 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitNotifications(const std::string& robot_email, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& access_token); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandlePrinterNotification(const std::string& printer_id); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PollForJobs(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a task to poll for jobs. Does nothing if a task is already 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scheduled. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScheduleJobPoll(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PingXmppServer(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScheduleXmppPing(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckXmppPingStatus(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPrintTokenStore* GetTokenStore(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our parent CloudPrintProxyBackend 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPrintProxyBackend* backend_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cloud Print authenticator. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<CloudPrintAuth> auth_; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cloud Print connector. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<CloudPrintConnector> connector_; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OAuth client info. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gaia::OAuthClientInfo oauth_client_info_; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notification (xmpp) handler. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<notifier::PushClient> push_client_; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicates whether XMPP notifications are currently enabled. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool notifications_enabled_; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The time when notifications were enabled. Valid only when 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifications_enabled_ is true. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks notifications_enabled_since_; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicates whether a task to poll for jobs has been scheduled. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool job_poll_scheduled_; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicates whether we should poll for jobs when we lose XMPP connection. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_job_poll_; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicates whether a task to ping xmpp server has been scheduled. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool xmpp_ping_scheduled_; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Number of XMPP pings pending reply from the server. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pending_xmpp_pings_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connector settings. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectorSettings settings_; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string robot_email_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CloudPrintTokenStore> token_store_; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Core); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintProxyBackend::CloudPrintProxyBackend( 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPrintProxyFrontend* frontend, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ConnectorSettings& settings, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gaia::OAuthClientInfo& oauth_client_info, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_job_poll) 171a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) : core_thread_("Chrome_CloudPrintProxyCoreThread"), 172a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) frontend_loop_(base::MessageLoop::current()), 173a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) frontend_(frontend) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(frontend_); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_ = new Core(this, settings, oauth_client_info, enable_job_poll); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)CloudPrintProxyBackend::~CloudPrintProxyBackend() { DCHECK(!core_.get()); } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CloudPrintProxyBackend::InitializeWithLsid( 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& lsid, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_robot_refresh_token, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_robot_email, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_user_email) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!core_thread_.Start()) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_thread_.message_loop()->PostTask( 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithLsid, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_.get(), lsid, last_robot_refresh_token, last_robot_email, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_user_email)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CloudPrintProxyBackend::InitializeWithToken( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& cloud_print_token) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!core_thread_.Start()) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_thread_.message_loop()->PostTask( 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithToken, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_.get(), cloud_print_token)); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CloudPrintProxyBackend::InitializeWithRobotToken( 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_oauth_refresh_token, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!core_thread_.Start()) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_thread_.message_loop()->PostTask( 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithRobotToken, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_.get(), robot_oauth_refresh_token, robot_email)); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CloudPrintProxyBackend::InitializeWithRobotAuthCode( 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_oauth_auth_code, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!core_thread_.Start()) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_thread_.message_loop()->PostTask( 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithRobotAuthCode, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_.get(), robot_oauth_auth_code, robot_email)); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Shutdown() { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_thread_.message_loop()->PostTask( 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::DoShutdown, core_.get())); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_thread_.Stop(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_ = NULL; // Releases reference to core_. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::UnregisterPrinters() { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_thread_.message_loop()->PostTask( 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::DoUnregisterPrinters, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_.get())); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintProxyBackend::Core::Core( 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPrintProxyBackend* backend, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ConnectorSettings& settings, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gaia::OAuthClientInfo& oauth_client_info, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_job_poll) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : backend_(backend), 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oauth_client_info_(oauth_client_info), 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_enabled_(false), 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_poll_scheduled_(false), 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enable_job_poll_(enable_job_poll), 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmpp_ping_scheduled_(false), 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_xmpp_pings_(0) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings_.CopyFrom(settings); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::CreateAuthAndConnector() { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!auth_.get()) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_ = new CloudPrintAuth(this, settings_.server_url(), oauth_client_info_, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings_.proxy_id()); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!connector_.get()) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connector_ = new CloudPrintConnector(this, settings_); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::DestroyAuthAndConnector() { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_ = NULL; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connector_ = NULL; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::DoInitializeWithLsid( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& lsid, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_robot_refresh_token, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_robot_email, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& last_user_email) { 281a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAuthAndConnector(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: The GAIA login is synchronous but that should be OK because we are in 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the CloudPrintProxyCoreThread and we cannot really do anything else until 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the GAIA signin is successful. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_->AuthenticateWithLsid(lsid, last_robot_refresh_token, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_robot_email, last_user_email); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::DoInitializeWithToken( 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& cloud_print_token) { 292a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAuthAndConnector(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_->AuthenticateWithToken(cloud_print_token); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::DoInitializeWithRobotToken( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_oauth_refresh_token, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email) { 300a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAuthAndConnector(); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_->AuthenticateWithRobotToken(robot_oauth_refresh_token, robot_email); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::DoInitializeWithRobotAuthCode( 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_oauth_auth_code, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email) { 308a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAuthAndConnector(); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_->AuthenticateWithRobotAuthCode(robot_oauth_auth_code, robot_email); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::OnAuthenticationComplete( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& access_token, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_oauth_refresh_token, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_email) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPrintTokenStore* token_store = GetTokenStore(); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool first_time = token_store->token().empty(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_store->SetToken(access_token); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) robot_email_ = robot_email; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let the frontend know that we have authenticated. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->frontend_loop_->PostTask( 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&Core::NotifyAuthenticated, this, robot_oauth_refresh_token, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) robot_email, user_email)); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_time) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitNotifications(robot_email, access_token); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are refreshing a token, update the XMPP token too. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(push_client_.get()); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->UpdateCredentials(robot_email, access_token); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start cloud print connector if needed. 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!connector_->IsRunning()) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!connector_->Start()) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let the frontend know that we do not have a print system. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->frontend_loop_->PostTask( 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Core::NotifyPrintSystemUnavailable, this)); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::OnInvalidCredentials() { 345a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CP_CONNECTOR: Auth Error"; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->frontend_loop_->PostTask( 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Core::NotifyAuthenticationFailed, this)); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::OnAuthFailed() { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CP_CONNECTOR: Authentication failed in connector."; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's stop connecter and refresh token. We'll restart connecter once 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new token available. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connector_->IsRunning()) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connector_->Stop(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Refresh Auth token. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_->RefreshAccessToken(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::InitNotifications( 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& access_token) { 365a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_xmpp_pings_ = 0; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier::NotifierOptions notifier_options; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier_options.request_context_getter = 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_service_process->GetServiceURLRequestContextGetter(); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier_options.auth_mechanism = "X-OAUTH2"; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier_options.try_ssltcp_first = true; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_ = notifier::PushClient::CreateDefault(notifier_options); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->AddObserver(this); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier::Subscription subscription; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subscription.channel = kCloudPrintPushNotificationsSource; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subscription.from = kCloudPrintPushNotificationsSource; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->UpdateSubscriptions( 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier::SubscriptionList(1, subscription)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->UpdateCredentials(robot_email, access_token); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::DoShutdown() { 384a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CP_CONNECTOR: Shutdown connector, id: " << settings_.proxy_id(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connector_->IsRunning()) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connector_->Stop(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Important to delete the PushClient on this thread. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (push_client_.get()) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->RemoveObserver(this); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_.reset(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_enabled_ = false; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_enabled_since_ = base::TimeTicks(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_store_.reset(); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestroyAuthAndConnector(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::DoUnregisterPrinters() { 403a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string access_token = GetTokenStore()->token(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<std::string> printer_ids; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connector_->GetPrinterIds(&printer_ids); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->frontend_loop_->PostTask( 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&Core::NotifyUnregisterPrinters, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, access_token, printer_ids)); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::HandlePrinterNotification( 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& printer_id) { 418a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CP_CONNECTOR: Handle printer notification, id: " << printer_id; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connector_->CheckForJobs(kJobFetchReasonNotified, printer_id); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::PollForJobs() { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CP_CONNECTOR: Polling for jobs."; 425a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check all printers for jobs. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connector_->CheckForJobs(kJobFetchReasonPoll, std::string()); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_poll_scheduled_ = false; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't have notifications and job polling is enabled, poll again 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after a while. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!notifications_enabled_ && enable_job_poll_) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleJobPoll(); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::ScheduleJobPoll() { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!job_poll_scheduled_) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta interval = base::TimeDelta::FromSeconds( 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RandInt(kMinJobPollIntervalSecs, kMaxJobPollIntervalSecs)); 440a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::PollForJobs, this), 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interval); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_poll_scheduled_ = true; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::PingXmppServer() { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmpp_ping_scheduled_ = false; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!push_client_.get()) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->SendPing(); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_xmpp_pings_++; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check ping status when we close to the limit. 459a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::CheckXmppPingStatus, this), 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(kXmppPingCheckIntervalSecs)); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule next ping if needed. 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (notifications_enabled_) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleXmppPing(); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::ScheduleXmppPing() { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!settings_.xmpp_ping_enabled()) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmpp_ping_scheduled_) { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta interval = base::TimeDelta::FromSeconds( 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RandInt(settings_.xmpp_ping_timeout_sec() * 0.9, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings_.xmpp_ping_timeout_sec() * 1.1)); 478a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CloudPrintProxyBackend::Core::PingXmppServer, this), 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interval); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmpp_ping_scheduled_ = true; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::CheckXmppPingStatus() { 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reconnect to XMPP. 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_xmpp_pings_ = 0; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_.reset(); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitNotifications(robot_email_, GetTokenStore()->token()); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintTokenStore* CloudPrintProxyBackend::Core::GetTokenStore() { 496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!token_store_.get()) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_store_.reset(new CloudPrintTokenStore); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return token_store_.get(); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::NotifyAuthenticated( 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_oauth_refresh_token, 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& robot_email, 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_email) { 506a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->frontend_loop_); 507a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) backend_->frontend_ 508a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ->OnAuthenticated(robot_oauth_refresh_token, robot_email, user_email); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::NotifyAuthenticationFailed() { 512a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->frontend_loop_); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->frontend_->OnAuthenticationFailed(); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::NotifyPrintSystemUnavailable() { 517a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->frontend_loop_); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->frontend_->OnPrintSystemUnavailable(); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::NotifyUnregisterPrinters( 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& auth_token, 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::list<std::string>& printer_ids) { 524a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->frontend_loop_); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->frontend_->OnUnregisterPrinters(auth_token, printer_ids); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::OnNotificationsEnabled() { 529a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_enabled_ = true; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_enabled_since_ = base::TimeTicks::Now(); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Notifications for connector " << settings_.proxy_id() 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " were enabled at " 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << notifications_enabled_since_.ToInternalValue(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notifications just got re-enabled. In this case we want to schedule 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a poll once for jobs we might have missed when we were dark. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that ScheduleJobPoll will not schedule again if a job poll task is 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already scheduled. 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleJobPoll(); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule periodic ping for XMPP notification channel. 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleXmppPing(); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::OnNotificationsDisabled( 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier::NotificationsDisabledReason reason) { 547a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_enabled_ = false; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Notifications for connector " << settings_.proxy_id() 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " disabled."; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_enabled_since_ = base::TimeTicks(); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We just lost notifications. This this case we want to schedule a 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // job poll if enable_job_poll_ is true. 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enable_job_poll_) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleJobPoll(); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::OnIncomingNotification( 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const notifier::Notification& notification) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we got some notification from the server, 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reset pending ping counter to 0. 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_xmpp_pings_ = 0; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CP_CONNECTOR: Incoming notification."; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == base::strcasecmp(kCloudPrintPushNotificationsSource, 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification.channel.c_str())) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandlePrinterNotification(notification.data); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintProxyBackend::Core::OnPingResponse() { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_xmpp_pings_ = 0; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "CP_CONNECTOR: Ping response received."; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cloud_print 578