C++程序  |  244行  |  7.92 KB

// Copyright 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.
//
// Simple system resources class that uses the current message loop
// for scheduling.  Assumes the current message loop is already
// running.

#ifndef SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_
#define SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_

#include <set>
#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/non_thread_safe.h"
#include "google/cacheinvalidation/include/system-resources.h"
#include "sync/base/sync_export.h"
#include "sync/notifier/invalidator_state.h"
#include "sync/notifier/state_writer.h"

namespace syncer {

class SyncLogger : public invalidation::Logger {
 public:
  SyncLogger();

  virtual ~SyncLogger();

  // invalidation::Logger implementation.
  virtual void Log(LogLevel level, const char* file, int line,
                   const char* format, ...) OVERRIDE;

  virtual void SetSystemResources(
      invalidation::SystemResources* resources) OVERRIDE;
};

class SyncInvalidationScheduler : public invalidation::Scheduler {
 public:
  SyncInvalidationScheduler();

  virtual ~SyncInvalidationScheduler();

  // Start and stop the scheduler.
  void Start();
  void Stop();

  // invalidation::Scheduler implementation.
  virtual void Schedule(invalidation::TimeDelta delay,
                        invalidation::Closure* task) OVERRIDE;

  virtual bool IsRunningOnThread() const OVERRIDE;

  virtual invalidation::Time GetCurrentTime() const OVERRIDE;

  virtual void SetSystemResources(
      invalidation::SystemResources* resources) OVERRIDE;

 private:
  // Runs the task, deletes it, and removes it from |posted_tasks_|.
  void RunPostedTask(invalidation::Closure* task);

  // Holds all posted tasks that have not yet been run.
  std::set<invalidation::Closure*> posted_tasks_;

  const base::MessageLoop* created_on_loop_;
  bool is_started_;
  bool is_stopped_;

  base::WeakPtrFactory<SyncInvalidationScheduler> weak_factory_;
};

// SyncNetworkChannel implements common tasks needed to interact with
// invalidation library:
//  - registering message and network status callbacks
//  - Encoding/Decoding message to ClientGatewayMessage
//  - notifying observers about network channel state change
// Implementation of particular network protocol should implement
// SendEncodedMessage and call NotifyStateChange and DeliverIncomingMessage.
class SYNC_EXPORT_PRIVATE SyncNetworkChannel
    : public NON_EXPORTED_BASE(invalidation::NetworkChannel) {
 public:
  class Observer {
   public:
    // Called when network channel state changes. Possible states are:
    //  - INVALIDATIONS_ENABLED : connection is established and working
    //  - TRANSIENT_INVALIDATION_ERROR : no network, connection lost, etc.
    //  - INVALIDATION_CREDENTIALS_REJECTED : Issues with auth token
    virtual void OnNetworkChannelStateChanged(
        InvalidatorState invalidator_state) = 0;
  };

  SyncNetworkChannel();

  virtual ~SyncNetworkChannel();

  // invalidation::NetworkChannel implementation.
  virtual void SendMessage(const std::string& outgoing_message) OVERRIDE;
  virtual void SetMessageReceiver(
      invalidation::MessageCallback* incoming_receiver) OVERRIDE;
  virtual void AddNetworkStatusReceiver(
      invalidation::NetworkStatusCallback* network_status_receiver) OVERRIDE;
  virtual void SetSystemResources(
      invalidation::SystemResources* resources) OVERRIDE;

  // Subclass should implement SendEncodedMessage to send encoded message to
  // Tango over network.
  virtual void SendEncodedMessage(const std::string& encoded_message) = 0;

  // Classes interested in network channel state changes should implement
  // SyncNetworkChannel::Observer and register here.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  const std::string& GetServiceContextForTest() const;

  int64 GetSchedulingHashForTest() const;

  static std::string EncodeMessageForTest(
      const std::string& message,
      const std::string& service_context,
      int64 scheduling_hash);

  static bool DecodeMessageForTest(
      const std::string& notification,
      std::string* message,
      std::string* service_context,
      int64* scheduling_hash);

 protected:
  // Subclass should notify about connection state through NotifyStateChange.
  void NotifyStateChange(InvalidatorState invalidator_state);
  // Subclass should call DeliverIncomingMessage for message to reach
  // invalidations library.
  void DeliverIncomingMessage(const std::string& message);

 private:
  typedef std::vector<invalidation::NetworkStatusCallback*>
      NetworkStatusReceiverList;

  static void EncodeMessage(
      std::string* encoded_message,
      const std::string& message,
      const std::string& service_context,
      int64 scheduling_hash);

  static bool DecodeMessage(
      const std::string& data,
      std::string* message,
      std::string* service_context,
      int64* scheduling_hash);

  // Callbacks into invalidation library
  scoped_ptr<invalidation::MessageCallback> incoming_receiver_;
  NetworkStatusReceiverList network_status_receivers_;

  // Last channel state for new network status receivers.
  InvalidatorState invalidator_state_;

  ObserverList<Observer> observers_;

  std::string service_context_;
  int64 scheduling_hash_;
};

class SyncStorage : public invalidation::Storage {
 public:
  SyncStorage(StateWriter* state_writer, invalidation::Scheduler* scheduler);

  virtual ~SyncStorage();

  void SetInitialState(const std::string& value) {
    cached_state_ = value;
  }

  // invalidation::Storage implementation.
  virtual void WriteKey(const std::string& key, const std::string& value,
                        invalidation::WriteKeyCallback* done) OVERRIDE;

  virtual void ReadKey(const std::string& key,
                       invalidation::ReadKeyCallback* done) OVERRIDE;

  virtual void DeleteKey(const std::string& key,
                         invalidation::DeleteKeyCallback* done) OVERRIDE;

  virtual void ReadAllKeys(
      invalidation::ReadAllKeysCallback* key_callback) OVERRIDE;

  virtual void SetSystemResources(
      invalidation::SystemResources* resources) OVERRIDE;

 private:
  // Runs the given storage callback with SUCCESS status and deletes it.
  void RunAndDeleteWriteKeyCallback(
      invalidation::WriteKeyCallback* callback);

  // Runs the given callback with the given value and deletes it.
  void RunAndDeleteReadKeyCallback(
      invalidation::ReadKeyCallback* callback, const std::string& value);

  StateWriter* state_writer_;
  invalidation::Scheduler* scheduler_;
  std::string cached_state_;
};

class SYNC_EXPORT_PRIVATE SyncSystemResources
    : public NON_EXPORTED_BASE(invalidation::SystemResources) {
 public:
  SyncSystemResources(SyncNetworkChannel* sync_network_channel,
                      StateWriter* state_writer);

  virtual ~SyncSystemResources();

  // invalidation::SystemResources implementation.
  virtual void Start() OVERRIDE;
  virtual void Stop() OVERRIDE;
  virtual bool IsStarted() const OVERRIDE;
  virtual void set_platform(const std::string& platform);
  virtual std::string platform() const OVERRIDE;
  virtual SyncLogger* logger() OVERRIDE;
  virtual SyncStorage* storage() OVERRIDE;
  virtual SyncNetworkChannel* network() OVERRIDE;
  virtual SyncInvalidationScheduler* internal_scheduler() OVERRIDE;
  virtual SyncInvalidationScheduler* listener_scheduler() OVERRIDE;

 private:
  bool is_started_;
  std::string platform_;
  scoped_ptr<SyncLogger> logger_;
  scoped_ptr<SyncInvalidationScheduler> internal_scheduler_;
  scoped_ptr<SyncInvalidationScheduler> listener_scheduler_;
  scoped_ptr<SyncStorage> storage_;
  // sync_network_channel_ is owned by SyncInvalidationListener.
  SyncNetworkChannel* sync_network_channel_;
};

}  // namespace syncer

#endif  // SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_