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#ifndef CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_CONNECTOR_H_
6#define CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_CONNECTOR_H_
7
8#include <list>
9#include <map>
10#include <string>
11
12#include "base/threading/thread.h"
13#include "base/values.h"
14#include "chrome/service/cloud_print/connector_settings.h"
15#include "chrome/service/cloud_print/print_system.h"
16#include "chrome/service/cloud_print/printer_job_handler.h"
17
18namespace cloud_print {
19
20// CloudPrintConnector handles top printer management tasks.
21//  - Matching local and cloud printers
22//  - Registration of local printers
23//  - Deleting cloud printers
24// All tasks are posted to the common queue (PendingTasks) and executed
25// one-by-one in FIFO order.
26// CloudPrintConnector will notify client over Client interface.
27class CloudPrintConnector
28    : public base::RefCountedThreadSafe<CloudPrintConnector>,
29      private PrintSystem::PrintServerWatcher::Delegate,
30      private PrinterJobHandlerDelegate,
31      private CloudPrintURLFetcherDelegate {
32 public:
33  class Client {
34   public:
35    virtual void OnAuthFailed() = 0;
36    virtual void OnXmppPingUpdated(int ping_timeout) = 0;
37   protected:
38     virtual ~Client() {}
39  };
40
41  CloudPrintConnector(Client* client, const ConnectorSettings& settings);
42
43  bool Start();
44  void Stop();
45  bool IsRunning();
46
47  // Return list of printer ids registered with CloudPrint.
48  void GetPrinterIds(std::list<std::string>* printer_ids);
49
50  // Check for jobs for specific printer. If printer id is empty
51  // jobs will be checked for all available printers.
52  void CheckForJobs(const std::string& reason, const std::string& printer_id);
53
54  // Update settings for specific printer.
55  void UpdatePrinterSettings(const std::string& printer_id);
56
57 private:
58  friend class base::RefCountedThreadSafe<CloudPrintConnector>;
59
60  // Prototype for a response handler.
61  typedef CloudPrintURLFetcher::ResponseAction
62      (CloudPrintConnector::*ResponseHandler)(
63          const net::URLFetcher* source,
64          const GURL& url,
65          base::DictionaryValue* json_data,
66          bool succeeded);
67
68  enum PendingTaskType {
69    PENDING_PRINTERS_NONE,
70    PENDING_PRINTERS_AVAILABLE,
71    PENDING_PRINTER_REGISTER,
72    PENDING_PRINTER_DELETE
73  };
74
75  // TODO(vitalybuka): Consider delete pending_tasks_ and just use MessageLoop.
76  struct PendingTask {
77    PendingTaskType type;
78    // Optional members, depending on type.
79    std::string printer_id;  // For pending delete.
80    printing::PrinterBasicInfo printer_info;  // For pending registration.
81
82    PendingTask() : type(PENDING_PRINTERS_NONE) {}
83    ~PendingTask() {}
84  };
85
86  virtual ~CloudPrintConnector();
87  // PrintServerWatcherDelegate implementation
88  virtual void OnPrinterAdded() OVERRIDE;
89  // PrinterJobHandler::Delegate implementation
90  virtual void OnPrinterDeleted(const std::string& printer_name) OVERRIDE;
91  virtual void OnAuthError() OVERRIDE;
92
93  // CloudPrintURLFetcher::Delegate implementation.
94  virtual CloudPrintURLFetcher::ResponseAction HandleRawData(
95      const net::URLFetcher* source,
96      const GURL& url,
97      const std::string& data) OVERRIDE;
98  virtual CloudPrintURLFetcher::ResponseAction HandleJSONData(
99      const net::URLFetcher* source,
100      const GURL& url,
101      base::DictionaryValue* json_data,
102      bool succeeded) OVERRIDE;
103  virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError() OVERRIDE;
104  virtual std::string GetAuthHeader() OVERRIDE;
105
106  // Begin response handlers
107  CloudPrintURLFetcher::ResponseAction HandlePrinterListResponse(
108      const net::URLFetcher* source,
109      const GURL& url,
110      base::DictionaryValue* json_data,
111      bool succeeded);
112
113  CloudPrintURLFetcher::ResponseAction HandlePrinterListResponseSettingsUpdate(
114      const net::URLFetcher* source,
115      const GURL& url,
116      base::DictionaryValue* json_data,
117      bool succeeded);
118
119  CloudPrintURLFetcher::ResponseAction HandlePrinterDeleteResponse(
120      const net::URLFetcher* source,
121      const GURL& url,
122      base::DictionaryValue* json_data,
123      bool succeeded);
124
125  CloudPrintURLFetcher::ResponseAction HandleRegisterPrinterResponse(
126      const net::URLFetcher* source,
127      const GURL& url,
128      base::DictionaryValue* json_data,
129      bool succeeded);
130  // End response handlers
131
132  // Helper functions for network requests.
133  void StartGetRequest(const GURL& url,
134                       int max_retries,
135                       ResponseHandler handler);
136  void StartPostRequest(CloudPrintURLFetcher::RequestType type,
137                        const GURL& url,
138                        int max_retries,
139                        const std::string& mime_type,
140                        const std::string& post_data,
141                        ResponseHandler handler);
142
143  // Reports a diagnostic message to the server.
144  void ReportUserMessage(const std::string& message_id,
145                         const std::string& failure_message);
146
147  bool RemovePrinterFromList(const std::string& printer_name,
148                             printing::PrinterList* printer_list);
149
150  void InitJobHandlerForPrinter(base::DictionaryValue* printer_data);
151
152  void UpdateSettingsFromPrintersList(base::DictionaryValue* json_data);
153
154  void AddPendingAvailableTask();
155  void AddPendingDeleteTask(const std::string& id);
156  void AddPendingRegisterTask(const printing::PrinterBasicInfo& info);
157  void AddPendingTask(const PendingTask& task);
158  void ProcessPendingTask();
159  void ContinuePendingTaskProcessing();
160  void OnPrintersAvailable();
161  void OnPrinterRegister(const printing::PrinterBasicInfo& info);
162  void OnPrinterDelete(const std::string& name);
163
164  void OnReceivePrinterCaps(
165      bool succeeded,
166      const std::string& printer_name,
167      const printing::PrinterCapsAndDefaults& caps_and_defaults);
168
169  // Register printer from the list.
170  void RegisterPrinters(const printing::PrinterList& printers);
171
172  bool IsSamePrinter(const std::string& name1, const std::string& name2) const;
173  bool InitPrintSystem();
174
175  void ScheduleStatsReport();
176  void ReportStats();
177
178  // CloudPrintConnector client.
179  Client* client_;
180  // Connector settings.
181  ConnectorSettings settings_;
182  // Pointer to current print system.
183  scoped_refptr<PrintSystem> print_system_;
184  // Watcher for print system updates.
185  scoped_refptr<PrintSystem::PrintServerWatcher>
186      print_server_watcher_;
187  // A map of printer id to job handler.
188  typedef std::map<std::string, scoped_refptr<PrinterJobHandler> >
189      JobHandlerMap;
190  JobHandlerMap job_handler_map_;
191  // Next response handler.
192  ResponseHandler next_response_handler_;
193  // The list of pending tasks to be done in the background.
194  std::list<PendingTask> pending_tasks_;
195  // The CloudPrintURLFetcher instance for the current request.
196  scoped_refptr<CloudPrintURLFetcher> request_;
197  // The CloudPrintURLFetcher instance for the user message request.
198  scoped_refptr<CloudPrintURLFetcher> user_message_request_;
199  base::WeakPtrFactory<CloudPrintConnector> stats_ptr_factory_;
200
201  DISALLOW_COPY_AND_ASSIGN(CloudPrintConnector);
202};
203
204}  // namespace cloud_print
205
206#endif  // CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_CONNECTOR_H_
207
208