1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef GOOGLE_APIS_GCM_ENGINE_MCS_CLIENT_H_ 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define GOOGLE_APIS_GCM_ENGINE_MCS_CLIENT_H_ 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <deque> 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <map> 10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string> 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <vector> 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/files/file_path.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/memory/linked_ptr.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/memory/weak_ptr.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gcm/base/gcm_export.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gcm/base/mcs_message.h" 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gcm/engine/connection_handler.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gcm/engine/gcm_store.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gcm/engine/heartbeat_manager.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace base { 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Clock; 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace base 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace google { 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace protobuf { 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MessageLite; 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace protobuf 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace google 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace mcs_proto { 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LoginRequest; 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace gcm { 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CollapseKey; 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class ConnectionFactory; 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass GCMStatsRecorder; 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)struct ReliablePacketInfo; 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// An MCS client. This client is in charge of all communications with an 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// MCS endpoint, and is capable of reliably sending/receiving GCM messages. 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// NOTE: Not thread safe. This class should live on the same thread as that 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// network requests are performed on. 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class GCM_EXPORT MCSClient { 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Any change made to this enum should have corresponding change in the 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // GetStateString(...) function. 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) enum State { 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UNINITIALIZED, // Uninitialized. 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOADED, // GCM Load finished, waiting to connect. 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CONNECTING, // Connection in progress. 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CONNECTED, // Connected and running. 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) }; 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Any change made to this enum should have corresponding change in the 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // GetMessageSendStatusString(...) function in mcs_client.cc. 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enum MessageSendStatus { 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Message was queued succcessfully. 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QUEUED, 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Message was sent to the server and the ACK was received. 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SENT, 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Message not saved, because total queue size limit reached. 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QUEUE_SIZE_LIMIT_REACHED, 670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Message not saved, because app queue size limit reached. 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) APP_QUEUE_SIZE_LIMIT_REACHED, 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Message too large to send. 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MESSAGE_TOO_LARGE, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Message not send becuase of TTL = 0 and no working connection. 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NO_CONNECTION_ON_ZERO_TTL, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Message exceeded TTL. 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TTL_EXCEEDED, 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // NOTE: always keep this entry at the end. Add new status types only 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // immediately above this line. Make sure to update the corresponding 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // histogram enum accordingly. 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SEND_STATUS_COUNT 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Callback for MCSClient's error conditions. 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(fgorski): Keeping it as a callback with intention to add meaningful 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // error information. 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef base::Callback<void()> ErrorCallback; 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Callback when a message is received. 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef base::Callback<void(const MCSMessage& message)> 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnMessageReceivedCallback; 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Callback when a message is sent (and receipt has been acknowledged by 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the MCS endpoint). 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef base::Callback< 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void(int64 user_serial_number, 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& app_id, 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& message_id, 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessageSendStatus status)> OnMessageSentCallback; 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MCSClient(const std::string& version_string, 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Clock* clock, 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ConnectionFactory* connection_factory, 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GCMStore* gcm_store, 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GCMStatsRecorder* recorder); 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~MCSClient(); 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Initialize the client. Will load any previous id/token information as well 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // as unacknowledged message information from the GCM storage, if it exists, 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // passing the id/token information back via |initialization_callback| along 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // with a |success == true| result. If no GCM information is present (and 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // this is therefore a fresh client), a clean GCM store will be created and 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // values of 0 will be returned via |initialization_callback| with 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // |success == true|. 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// If an error loading the GCM store is encountered, 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // |initialization_callback| will be invoked with |success == false|. 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Initialize(const ErrorCallback& initialization_callback, 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const OnMessageReceivedCallback& message_received_callback, 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const OnMessageSentCallback& message_sent_callback, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<GCMStore::LoadResult> load_result); 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Logs the client into the server. Client must be initialized. 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // |android_id| and |security_token| are optional if this is not a new 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // client, else they must be non-zero. 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Successful login will result in |message_received_callback| being invoked 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // with a valid LoginResponse. 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Login failure (typically invalid id/token) will shut down the client, and 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // |initialization_callback| to be invoked with |success = false|. 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Login(uint64 android_id, uint64 security_token); 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Sends a message, with or without reliable message queueing (RMQ) support. 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Will asynchronously invoke the OnMessageSent callback regardless. 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Whether to use RMQ depends on whether the protobuf has |ttl| set or not. 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |ttl == 0| denotes the message should only be sent if the connection is 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // open. |ttl > 0| will keep the message saved for |ttl| seconds, after which 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // it will be dropped if it was unable to be sent. When a message is dropped, 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |message_sent_callback_| is invoked with a TTL expiration error. 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SendMessage(const MCSMessage& message); 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Returns the current state of the client. 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) State state() const { return state_; } 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Returns the size of the send message queue. 1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int GetSendQueueSize() const; 1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Returns the size of the resend messaage queue. 1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int GetResendQueueSize() const; 1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Returns text representation of the state enum. 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string GetStateString() const; 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef uint32 StreamId; 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef std::string PersistentId; 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef std::vector<StreamId> StreamIdList; 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef std::vector<PersistentId> PersistentIdList; 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef std::map<StreamId, PersistentId> StreamIdToPersistentIdMap; 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef linked_ptr<ReliablePacketInfo> MCSPacketInternal; 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Resets the internal state and builds a new login request, acknowledging 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // any pending server-to-device messages and rebuilding the send queue 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // from all unacknowledged device-to-server messages. 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Should only be called when the connection has been reset. 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void ResetStateAndBuildLoginRequest(mcs_proto::LoginRequest* request); 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Send a heartbeat to the MCS server. 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void SendHeartbeat(); 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // GCM Store callback. 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnGCMUpdateFinished(bool success); 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Attempt to send a message. 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void MaybeSendMessage(); 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Helper for sending a protobuf along with any unacknowledged ids to the 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // wire. 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void SendPacketToWire(ReliablePacketInfo* packet_info); 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Handle a data message sent to the MCS client system from the MCS server. 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void HandleMCSDataMesssage( 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<google::protobuf::MessageLite> protobuf); 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Handle a packet received over the wire. 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void HandlePacketFromWire(scoped_ptr<google::protobuf::MessageLite> protobuf); 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ReliableMessageQueue acknowledgment helpers. 183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Handle a StreamAck sent by the server confirming receipt of all 184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // messages up to the message with stream id |last_stream_id_received|. 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void HandleStreamAck(StreamId last_stream_id_received_); 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Handle a SelectiveAck sent by the server confirming all messages 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // in |id_list|. 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void HandleSelectiveAck(const PersistentIdList& id_list); 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Handle server confirmation of a device message, including device's 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // acknowledgment of receipt of messages. 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void HandleServerConfirmedReceipt(StreamId device_stream_id); 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Generates a new persistent id for messages. 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Virtual for testing. 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual PersistentId GetNextPersistentId(); 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Helper for the heartbeat manager to signal a connection reset. 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnConnectionResetByHeartbeat(); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Runs the message_sent_callback_ with send |status| of the |protobuf|. 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void NotifyMessageSendStatus(const google::protobuf::MessageLite& protobuf, 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessageSendStatus status); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Pops the next message from the front of the send queue (cleaning up 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // any associated state). 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MCSPacketInternal PopMessageForSend(); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Local version string. Sent on login. 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string version_string_; 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Clock for enforcing TTL. Passed in for testing. 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Clock* const clock_; 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Client state. 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) State state_; 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Callbacks for owner. 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ErrorCallback mcs_error_callback_; 219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnMessageReceivedCallback message_received_callback_; 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnMessageSentCallback message_sent_callback_; 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The android id and security token in use by this device. 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 android_id_; 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint64 security_token_; 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Factory for creating new connections and connection handlers. 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ConnectionFactory* connection_factory_; 228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Connection handler to handle all over-the-wire protocol communication 230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // with the mobile connection server. 231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ConnectionHandler* connection_handler_; 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ----- Reliablie Message Queue section ----- 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Note: all queues/maps are ordered from oldest (front/begin) message to 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // most recent (back/end). 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Send/acknowledge queues. 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::deque<MCSPacketInternal> to_send_; 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::deque<MCSPacketInternal> to_resend_; 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Map of collapse keys to their pending messages. 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::map<CollapseKey, ReliablePacketInfo*> collapse_key_map_; 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Last device_to_server stream id acknowledged by the server. 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StreamId last_device_to_server_stream_id_received_; 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Last server_to_device stream id acknowledged by this device. 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StreamId last_server_to_device_stream_id_received_; 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The stream id for the last sent message. A new message should consume 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // stream_id_out_ + 1. 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StreamId stream_id_out_; 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The stream id of the last received message. The LoginResponse will always 252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // have a stream id of 1, and stream ids increment by 1 for each received 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // message. 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StreamId stream_id_in_; 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The server messages that have not been acked by the device yet. Keyed by 257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // server stream id. 258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StreamIdToPersistentIdMap unacked_server_ids_; 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Those server messages that have been acked. They must remain tracked 261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // until the ack message is itself confirmed. The list of all message ids 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // acknowledged are keyed off the device stream id of the message that 263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // acknowledged them. 264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::map<StreamId, PersistentIdList> acked_server_ids_; 265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Those server messages from a previous connection that were not fully 267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // acknowledged. They do not have associated stream ids, and will be 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // acknowledged on the next login attempt. 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PersistentIdList restored_unackeds_server_ids_; 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The GCM persistent store. Not owned. 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GCMStore* gcm_store_; 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Manager to handle triggering/detecting heartbeats. 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HeartbeatManager heartbeat_manager_; 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Recorder that records GCM activities for debugging purpose. Not owned. 2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GCMStatsRecorder* recorder_; 2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::WeakPtrFactory<MCSClient> weak_ptr_factory_; 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MCSClient); 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace gcm 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif // GOOGLE_APIS_GCM_ENGINE_MCS_CLIENT_H_ 288