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 // An invalidator that uses p2p invalidations based on XMPP push
      6 // notifications.  Used only for sync integration tests.
      7 
      8 #ifndef COMPONENTS_INVALIDATION_P2P_INVALIDATOR_H_
      9 #define COMPONENTS_INVALIDATION_P2P_INVALIDATOR_H_
     10 
     11 #include <string>
     12 
     13 #include "base/compiler_specific.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "base/observer_list.h"
     18 #include "base/threading/thread_checker.h"
     19 #include "components/invalidation/invalidation_export.h"
     20 #include "components/invalidation/invalidator_registrar.h"
     21 #include "jingle/notifier/base/notifier_options.h"
     22 #include "jingle/notifier/listener/push_client.h"
     23 #include "jingle/notifier/listener/push_client_observer.h"
     24 #include "sync/internal_api/public/base/invalidator_state.h"
     25 #include "sync/internal_api/public/base/model_type.h"
     26 #include "sync/notifier/invalidator.h"
     27 #include "sync/notifier/object_id_invalidation_map.h"
     28 
     29 namespace notifier {
     30 class PushClient;
     31 }  // namespace notifier
     32 
     33 namespace syncer {
     34 
     35 // The channel to use for sync notifications.
     36 INVALIDATION_EXPORT extern const char kSyncP2PNotificationChannel[];
     37 
     38 // The intended recipient(s) of a P2P notification.
     39 enum P2PNotificationTarget {
     40   NOTIFY_SELF,
     41   FIRST_NOTIFICATION_TARGET = NOTIFY_SELF,
     42   NOTIFY_OTHERS,
     43   NOTIFY_ALL,
     44   LAST_NOTIFICATION_TARGET = NOTIFY_ALL
     45 };
     46 
     47 INVALIDATION_EXPORT_PRIVATE std::string P2PNotificationTargetToString(
     48     P2PNotificationTarget target);
     49 
     50 // If |target_str| can't be parsed, assumes NOTIFY_SELF.
     51 INVALIDATION_EXPORT_PRIVATE P2PNotificationTarget
     52 P2PNotificationTargetFromString(const std::string& target_str);
     53 
     54 // Helper notification data class that can be serialized to and
     55 // deserialized from a string.
     56 class INVALIDATION_EXPORT_PRIVATE P2PNotificationData {
     57  public:
     58   // Initializes with an empty sender ID, target set to NOTIFY_SELF,
     59   // and empty changed types.
     60   P2PNotificationData();
     61   P2PNotificationData(const std::string& sender_id,
     62                       P2PNotificationTarget target,
     63                       const ObjectIdInvalidationMap& invalidation_map);
     64 
     65   ~P2PNotificationData();
     66 
     67   // Returns true if the given ID is targeted by this notification.
     68   bool IsTargeted(const std::string& id) const;
     69 
     70   const ObjectIdInvalidationMap& GetIdInvalidationMap() const;
     71 
     72   bool Equals(const P2PNotificationData& other) const;
     73 
     74   std::string ToString() const;
     75 
     76   // Returns whether parsing |str| was successful.  If parsing was
     77   // unsuccessful, the state of the notification is undefined.
     78   bool ResetFromString(const std::string& str);
     79 
     80  private:
     81   // The unique ID of the client that sent the notification.
     82   std::string sender_id_;
     83   // The intendent recipient(s) of the notification.
     84   P2PNotificationTarget target_;
     85   // The invalidation map for the notification.
     86   ObjectIdInvalidationMap invalidation_map_;
     87 };
     88 
     89 class INVALIDATION_EXPORT_PRIVATE P2PInvalidator
     90     : public Invalidator,
     91       public NON_EXPORTED_BASE(notifier::PushClientObserver) {
     92  public:
     93   // The |send_notification_target| parameter was added to allow us to send
     94   // self-notifications in some cases, but not others.  The value should be
     95   // either NOTIFY_ALL to send notifications to all clients, or NOTIFY_OTHERS
     96   // to send notifications to all clients except for the one that triggered the
     97   // notification.  See crbug.com/97780.
     98   P2PInvalidator(scoped_ptr<notifier::PushClient> push_client,
     99                  const std::string& invalidator_client_id,
    100                  P2PNotificationTarget send_notification_target);
    101 
    102   virtual ~P2PInvalidator();
    103 
    104   // Invalidator implementation.
    105   virtual void RegisterHandler(InvalidationHandler* handler) OVERRIDE;
    106   virtual void UpdateRegisteredIds(InvalidationHandler* handler,
    107                                    const ObjectIdSet& ids) OVERRIDE;
    108   virtual void UnregisterHandler(InvalidationHandler* handler) OVERRIDE;
    109   virtual InvalidatorState GetInvalidatorState() const OVERRIDE;
    110   virtual void UpdateCredentials(
    111       const std::string& email, const std::string& token) OVERRIDE;
    112   virtual void RequestDetailedStatus(
    113       base::Callback<void(const base::DictionaryValue&)> callback) const
    114       OVERRIDE;
    115 
    116   // PushClientObserver implementation.
    117   virtual void OnNotificationsEnabled() OVERRIDE;
    118   virtual void OnNotificationsDisabled(
    119       notifier::NotificationsDisabledReason reason) OVERRIDE;
    120   virtual void OnIncomingNotification(
    121       const notifier::Notification& notification) OVERRIDE;
    122 
    123   void SendInvalidation(const ObjectIdSet& ids);
    124 
    125   void SendNotificationDataForTest(
    126       const P2PNotificationData& notification_data);
    127 
    128  private:
    129   void SendNotificationData(const P2PNotificationData& notification_data);
    130 
    131   base::ThreadChecker thread_checker_;
    132 
    133   InvalidatorRegistrar registrar_;
    134 
    135   // The push client.
    136   scoped_ptr<notifier::PushClient> push_client_;
    137   // Our unique ID.
    138   std::string invalidator_client_id_;
    139   // Whether we have called UpdateCredentials() yet.
    140   bool logged_in_;
    141   bool notifications_enabled_;
    142   // Which set of clients should be sent notifications.
    143   P2PNotificationTarget send_notification_target_;
    144 
    145   DISALLOW_COPY_AND_ASSIGN(P2PInvalidator);
    146 };
    147 
    148 }  // namespace syncer
    149 
    150 #endif  // COMPONENTS_INVALIDATION_P2P_INVALIDATOR_H_
    151