#ifndef GOOGLE_APIS_GCM_GCM_CLIENT_IMPL_H_
#define GOOGLE_APIS_GCM_GCM_CLIENT_IMPL_H_
#include <map>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "google_apis/gcm/base/mcs_message.h"
#include "google_apis/gcm/engine/gcm_store.h"
#include "google_apis/gcm/engine/mcs_client.h"
#include "google_apis/gcm/engine/registration_request.h"
#include "google_apis/gcm/engine/unregistration_request.h"
#include "google_apis/gcm/gcm_client.h"
#include "google_apis/gcm/protocol/android_checkin.pb.h"
#include "net/base/net_log.h"
#include "net/url_request/url_request_context_getter.h"
class GURL;
namespace base {
class Clock;
class FilePath;
}
namespace net {
class HttpNetworkSession;
}
namespace gcm {
class CheckinRequest;
class ConnectionFactory;
class GCMClientImplTest;
class GCM_EXPORT GCMInternalsBuilder {
public:
GCMInternalsBuilder();
virtual ~GCMInternalsBuilder();
virtual scoped_ptr<base::Clock> BuildClock();
virtual scoped_ptr<GCMStore> BuildGCMStore(
const base::FilePath& path,
const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner);
virtual scoped_ptr<MCSClient> BuildMCSClient(
const std::string& version,
base::Clock* clock,
ConnectionFactory* connection_factory,
GCMStore* gcm_store);
virtual scoped_ptr<ConnectionFactory> BuildConnectionFactory(
const std::vector<GURL>& endpoints,
const net::BackoffEntry::Policy& backoff_policy,
scoped_refptr<net::HttpNetworkSession> network_session,
net::NetLog* net_log);
};
class GCM_EXPORT GCMClientImpl : public GCMClient {
public:
explicit GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder);
virtual ~GCMClientImpl();
virtual void Initialize(
const checkin_proto::ChromeBuildProto& chrome_build_proto,
const base::FilePath& store_path,
const std::vector<std::string>& account_ids,
const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
const scoped_refptr<net::URLRequestContextGetter>&
url_request_context_getter,
Delegate* delegate) OVERRIDE;
virtual void Load() OVERRIDE;
virtual void Stop() OVERRIDE;
virtual void CheckOut() OVERRIDE;
virtual void Register(const std::string& app_id,
const std::vector<std::string>& sender_ids) OVERRIDE;
virtual void Unregister(const std::string& app_id) OVERRIDE;
virtual void Send(const std::string& app_id,
const std::string& receiver_id,
const OutgoingMessage& message) OVERRIDE;
virtual GCMStatistics GetStatistics() const OVERRIDE;
private:
enum State {
UNINITIALIZED,
INITIALIZED,
LOADING,
INITIAL_DEVICE_CHECKIN,
READY,
};
struct GCM_EXPORT CheckinInfo {
CheckinInfo() : android_id(0), secret(0) {}
bool IsValid() const { return android_id != 0 && secret != 0; }
void Reset() {
android_id = 0;
secret = 0;
}
uint64 android_id;
uint64 secret;
};
typedef std::map<std::string, RegistrationRequest*>
PendingRegistrationRequests;
typedef std::map<std::string, UnregistrationRequest*>
PendingUnregistrationRequests;
friend class GCMClientImplTest;
std::string GetStateString() const;
void OnMessageReceivedFromMCS(const gcm::MCSMessage& message);
void OnMessageSentToMCS(int64 user_serial_number,
const std::string& app_id,
const std::string& message_id,
MCSClient::MessageSendStatus status);
void OnMCSError();
void OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result);
void InitializeMCSClient(scoped_ptr<GCMStore::LoadResult> result);
void OnFirstTimeDeviceCheckinCompleted(const CheckinInfo& checkin_info);
void StartMCSLogin();
void ResetState();
void OnReady();
void StartCheckin();
void OnCheckinCompleted(uint64 android_id,
uint64 security_token);
void SchedulePeriodicCheckin(const base::Time& last_checkin_time);
void SetLastCheckinTimeCallback(bool success);
void SetDeviceCredentialsCallback(bool success);
void UpdateRegistrationCallback(bool success);
void OnRegisterCompleted(const std::string& app_id,
const std::vector<std::string>& sender_ids,
RegistrationRequest::Status status,
const std::string& registration_id);
void OnUnregisterCompleted(const std::string& app_id,
UnregistrationRequest::Status status);
void OnGCMStoreDestroyed(bool success);
void HandleIncomingMessage(const gcm::MCSMessage& message);
void HandleIncomingDataMessage(
const mcs_proto::DataMessageStanza& data_message_stanza,
MessageData& message_data);
void HandleIncomingSendError(
const mcs_proto::DataMessageStanza& data_message_stanza,
MessageData& message_data);
scoped_ptr<GCMInternalsBuilder> internals_builder_;
State state_;
Delegate* delegate_;
CheckinInfo device_checkin_info_;
scoped_ptr<base::Clock> clock_;
checkin_proto::ChromeBuildProto chrome_build_proto_;
scoped_ptr<GCMStore> gcm_store_;
scoped_refptr<net::HttpNetworkSession> network_session_;
net::BoundNetLog net_log_;
scoped_ptr<ConnectionFactory> connection_factory_;
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
scoped_ptr<MCSClient> mcs_client_;
scoped_ptr<CheckinRequest> checkin_request_;
std::vector<std::string> account_ids_;
RegistrationInfoMap registrations_;
PendingRegistrationRequests pending_registration_requests_;
STLValueDeleter<PendingRegistrationRequests>
pending_registration_requests_deleter_;
PendingUnregistrationRequests pending_unregistration_requests_;
STLValueDeleter<PendingUnregistrationRequests>
pending_unregistration_requests_deleter_;
base::WeakPtrFactory<GCMClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(GCMClientImpl);
};
}
#endif