Home | History | Annotate | Download | only in invalidation
      1 // Copyright 2014 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 COMPONENTS_INVALIDATION_GCM_NETWORK_CHANNEL_H_
      6 #define COMPONENTS_INVALIDATION_GCM_NETWORK_CHANNEL_H_
      7 
      8 #include <string>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/threading/non_thread_safe.h"
     14 #include "components/invalidation/gcm_network_channel_delegate.h"
     15 #include "components/invalidation/invalidation_export.h"
     16 #include "components/invalidation/sync_system_resources.h"
     17 #include "net/base/backoff_entry.h"
     18 #include "net/base/network_change_notifier.h"
     19 #include "net/url_request/url_fetcher_delegate.h"
     20 #include "url/gurl.h"
     21 
     22 class GoogleServiceAuthError;
     23 
     24 namespace syncer {
     25 class GCMNetworkChannel;
     26 
     27 // POD with copy of some statuses for debugging purposes.
     28 struct GCMNetworkChannelDiagnostic {
     29   explicit GCMNetworkChannelDiagnostic(GCMNetworkChannel* parent);
     30 
     31   // Collect all the internal variables in a single readable dictionary.
     32   scoped_ptr<base::DictionaryValue> CollectDebugData() const;
     33 
     34   // TODO(pavely): Move this toString to a more appropiate place in GCMClient.
     35   std::string GCMClientResultToString(
     36       const gcm::GCMClient::Result result) const;
     37 
     38   GCMNetworkChannel* parent_;
     39   bool last_message_empty_echo_token_;
     40   base::Time last_message_received_time_;
     41   int last_post_response_code_;
     42   std::string registration_id_;
     43   gcm::GCMClient::Result registration_result_;
     44   int sent_messages_count_;
     45 };
     46 
     47 // GCMNetworkChannel is an implementation of SyncNetworkChannel that routes
     48 // messages through GCMService.
     49 class INVALIDATION_EXPORT_PRIVATE GCMNetworkChannel
     50     : public SyncNetworkChannel,
     51       public net::URLFetcherDelegate,
     52       public net::NetworkChangeNotifier::NetworkChangeObserver,
     53       public base::NonThreadSafe {
     54  public:
     55   GCMNetworkChannel(
     56       scoped_refptr<net::URLRequestContextGetter> request_context_getter,
     57       scoped_ptr<GCMNetworkChannelDelegate> delegate);
     58 
     59   virtual ~GCMNetworkChannel();
     60 
     61   // invalidation::NetworkChannel implementation.
     62   virtual void SendMessage(const std::string& message) OVERRIDE;
     63   virtual void SetMessageReceiver(
     64       invalidation::MessageCallback* incoming_receiver) OVERRIDE;
     65 
     66   // SyncNetworkChannel implementation.
     67   virtual void UpdateCredentials(const std::string& email,
     68                                  const std::string& token) OVERRIDE;
     69   virtual int GetInvalidationClientType() OVERRIDE;
     70   virtual void RequestDetailedStatus(
     71       base::Callback<void(const base::DictionaryValue&)> callback) OVERRIDE;
     72 
     73   // URLFetcherDelegate implementation.
     74   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
     75 
     76   // NetworkChangeObserver implementation.
     77   virtual void OnNetworkChanged(
     78       net::NetworkChangeNotifier::ConnectionType connection_type) OVERRIDE;
     79 
     80  protected:
     81   void ResetRegisterBackoffEntryForTest(
     82       const net::BackoffEntry::Policy* policy);
     83 
     84   virtual GURL BuildUrl(const std::string& registration_id);
     85 
     86  private:
     87   friend class GCMNetworkChannelTest;
     88   void Register();
     89   void OnRegisterComplete(const std::string& registration_id,
     90                           gcm::GCMClient::Result result);
     91   void RequestAccessToken();
     92   void OnGetTokenComplete(const GoogleServiceAuthError& error,
     93                           const std::string& token);
     94   void OnIncomingMessage(const std::string& message,
     95                          const std::string& echo_token);
     96   void OnConnectionStateChanged(bool online);
     97   void UpdateGcmChannelState(bool online);
     98   void UpdateHttpChannelState(bool online);
     99   // Base64 encoding/decoding with URL safe alphabet.
    100   // http://tools.ietf.org/html/rfc4648#page-7
    101   static void Base64EncodeURLSafe(const std::string& input,
    102                                   std::string* output);
    103   static bool Base64DecodeURLSafe(const std::string& input,
    104                                   std::string* output);
    105 
    106   scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
    107   scoped_ptr<GCMNetworkChannelDelegate> delegate_;
    108 
    109   // Message is saved until all conditions are met: there is valid
    110   // registration_id and access_token.
    111   std::string cached_message_;
    112 
    113   // Access token is saved because in case of auth failure from server we need
    114   // to invalidate it.
    115   std::string access_token_;
    116 
    117   // GCM registration_id is requested one at startup and never refreshed until
    118   // next restart.
    119   std::string registration_id_;
    120   scoped_ptr<net::BackoffEntry> register_backoff_entry_;
    121 
    122   scoped_ptr<net::URLFetcher> fetcher_;
    123 
    124   // cacheinvalidation client receives echo_token with incoming message from
    125   // GCM and shuld include it in headers with outgoing message over http.
    126   std::string echo_token_;
    127 
    128   // State of gcm and http channels. GCMNetworkChannel will only report
    129   // INVALIDATIONS_ENABLED if both channels are online.
    130   bool gcm_channel_online_;
    131   bool http_channel_online_;
    132 
    133   GCMNetworkChannelDiagnostic diagnostic_info_;
    134 
    135   base::WeakPtrFactory<GCMNetworkChannel> weak_factory_;
    136 
    137   DISALLOW_COPY_AND_ASSIGN(GCMNetworkChannel);
    138 };
    139 
    140 }  // namespace syncer
    141 
    142 #endif  // COMPONENTS_INVALIDATION_GCM_NETWORK_CHANNEL_H_
    143