diff options
author | fgorski <fgorski@chromium.org> | 2015-10-28 15:48:46 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-28 22:49:30 +0000 |
commit | 44f2b96cbe3b2168af54e3fa4c7464f3607474e6 (patch) | |
tree | 995e02e5b964a3296ca29b522476e159215c927f /google_apis | |
parent | 3568d9cebe7b59f2b24a50690a90469e4afd79f6 (diff) | |
download | chromium_src-44f2b96cbe3b2168af54e3fa4c7464f3607474e6.zip chromium_src-44f2b96cbe3b2168af54e3fa4c7464f3607474e6.tar.gz chromium_src-44f2b96cbe3b2168af54e3fa4c7464f3607474e6.tar.bz2 |
[GCM] Adding handling of the immediate ack to Chrome
If a message carries immediate_ack bit, stream ack will be sent
immediately upon receipt.
This patch also adds a test for that behavior.
BUG=548766
Review URL: https://codereview.chromium.org/1408403006
Cr-Commit-Position: refs/heads/master@{#356679}
Diffstat (limited to 'google_apis')
-rw-r--r-- | google_apis/gcm/base/mcs_util.cc | 8 | ||||
-rw-r--r-- | google_apis/gcm/base/mcs_util.h | 4 | ||||
-rw-r--r-- | google_apis/gcm/engine/mcs_client.cc | 5 | ||||
-rw-r--r-- | google_apis/gcm/engine/mcs_client_unittest.cc | 264 | ||||
-rw-r--r-- | google_apis/gcm/protocol/mcs.proto | 16 |
5 files changed, 164 insertions, 133 deletions
diff --git a/google_apis/gcm/base/mcs_util.cc b/google_apis/gcm/base/mcs_util.cc index 7dd9d7b..b5fb928 100644 --- a/google_apis/gcm/base/mcs_util.cc +++ b/google_apis/gcm/base/mcs_util.cc @@ -259,4 +259,12 @@ int GetTTL(const google::protobuf::MessageLite& protobuf) { return data_message->ttl(); } +bool IsImmediateAckRequested(const google::protobuf::MessageLite& protobuf) { + if (protobuf.GetTypeName() != kProtoNames[kDataMessageStanzaTag]) + return false; + const mcs_proto::DataMessageStanza* data_message = + reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf); + return data_message->has_immediate_ack() && data_message->immediate_ack(); +} + } // namespace gcm diff --git a/google_apis/gcm/base/mcs_util.h b/google_apis/gcm/base/mcs_util.h index 95d97f2..e6fc1e0 100644 --- a/google_apis/gcm/base/mcs_util.h +++ b/google_apis/gcm/base/mcs_util.h @@ -89,6 +89,10 @@ GCM_EXPORT bool HasTTLExpired(const google::protobuf::MessageLite& protobuf, base::Clock* clock); GCM_EXPORT int GetTTL(const google::protobuf::MessageLite& protobuf); +// Returns whether the message was sent with an immediate ack request. +GCM_EXPORT bool IsImmediateAckRequested( + const google::protobuf::MessageLite& protobuf); + } // namespace gcm #endif // GOOGLE_APIS_GCM_BASE_MCS_UTIL_H_ diff --git a/google_apis/gcm/engine/mcs_client.cc b/google_apis/gcm/engine/mcs_client.cc index f20d937..2e52ddb 100644 --- a/google_apis/gcm/engine/mcs_client.cc +++ b/google_apis/gcm/engine/mcs_client.cc @@ -681,8 +681,9 @@ void MCSClient::HandlePacketFromWire( << ", stream id " << stream_id_in_ << " and last stream id received " << last_stream_id_received; - if (unacked_server_ids_.size() > 0 && - unacked_server_ids_.size() % kUnackedMessageBeforeStreamAck == 0) { + if ((unacked_server_ids_.size() > 0 && + unacked_server_ids_.size() % kUnackedMessageBeforeStreamAck == 0) || + IsImmediateAckRequested(*protobuf)) { SendMessage(MCSMessage(kIqStanzaTag, BuildStreamAck())); } diff --git a/google_apis/gcm/engine/mcs_client_unittest.cc b/google_apis/gcm/engine/mcs_client_unittest.cc index 6c7ea72..961c36d 100644 --- a/google_apis/gcm/engine/mcs_client_unittest.cc +++ b/google_apis/gcm/engine/mcs_client_unittest.cc @@ -41,6 +41,13 @@ const int kAckLimitSize = 10; // TTL value for reliable messages. const int kTTLValue = 5 * 60; // 5 minutes. +// Specifies whether immediate ACK should be requested. +enum RequestImmediateAck { + IMMEDIATE_ACK_IGNORE, // Ignores the field and does not set it. + IMMEDIATE_ACK_NO, // Sets the field to false. + IMMEDIATE_ACK_YES // Sets the field to true. +}; + // Helper for building arbitrary data messages. MCSMessage BuildDataMessage(const std::string& from, const std::string& category, @@ -51,7 +58,8 @@ MCSMessage BuildDataMessage(const std::string& from, uint64 sent, int queued, const std::string& token, - const uint64& user_id) { + const uint64& user_id, + RequestImmediateAck immediate_ack) { mcs_proto::DataMessageStanza data_message; data_message.set_id(message_id); data_message.set_from(from); @@ -64,6 +72,9 @@ MCSMessage BuildDataMessage(const std::string& from, data_message.set_queued(queued); data_message.set_token(token); data_message.set_device_user_id(user_id); + if (immediate_ack != IMMEDIATE_ACK_IGNORE) { + data_message.set_immediate_ack(immediate_ack == IMMEDIATE_ACK_YES); + } return MCSMessage(kDataMessageStanzaTag, data_message); } @@ -342,8 +353,8 @@ TEST_F(MCSClientTest, SendMessageNoRMQ) { BuildMCSClient(); InitializeClient(); LoginClient(std::vector<std::string>()); - MCSMessage message( - BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0, "", 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0, + "", 0, IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(message); mcs_client()->SendMessage(message); EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); @@ -356,8 +367,8 @@ TEST_F(MCSClientTest, SendMessageNoRMQWhileDisconnected) { InitializeClient(); EXPECT_TRUE(sent_message_id().empty()); - MCSMessage message( - BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0, "", 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0, + "", 0, IMMEDIATE_ACK_NO)); mcs_client()->SendMessage(message); // Message sent callback should be invoked, but no message should actually @@ -372,8 +383,9 @@ TEST_F(MCSClientTest, SendMessageRMQ) { BuildMCSClient(); InitializeClient(); LoginClient(std::vector<std::string>()); - MCSMessage message(BuildDataMessage( - "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, "1", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(message); mcs_client()->SendMessage(message); EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); @@ -386,8 +398,9 @@ TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) { InitializeClient(); LoginClient(std::vector<std::string>()); GetFakeHandler()->set_fail_send(true); - MCSMessage message(BuildDataMessage( - "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, "1", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); // The initial (failed) send. GetFakeHandler()->ExpectOutgoingMessage(message); @@ -395,8 +408,9 @@ TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) { GetFakeHandler()->ExpectOutgoingMessage(MCSMessage( kLoginRequestTag, BuildLoginRequest(kAndroidId, kSecurityToken, ""))); // The second (re)send. - MCSMessage message2(BuildDataMessage( - "from", "category", "X", 1, "1", kTTLValue, 1, kTTLValue - 1, "", 0)); + MCSMessage message2(BuildDataMessage("from", "category", "X", 1, "1", + kTTLValue, 1, kTTLValue - 1, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(message2); mcs_client()->SendMessage(message); PumpLoop(); // Wait for the queuing to happen. @@ -427,8 +441,9 @@ TEST_F(MCSClientTest, SendMessageRMQOnRestart) { InitializeClient(); LoginClient(std::vector<std::string>()); GetFakeHandler()->set_fail_send(true); - MCSMessage message(BuildDataMessage( - "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, "1", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); // The initial (failed) send. GetFakeHandler()->ExpectOutgoingMessage(message); @@ -443,8 +458,9 @@ TEST_F(MCSClientTest, SendMessageRMQOnRestart) { InitializeClient(); clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); - MCSMessage message2(BuildDataMessage( - "from", "category", "X", 1, "1", kTTLValue, 1, kTTLValue - 1, "", 0)); + MCSMessage message2(BuildDataMessage("from", "category", "X", 1, "1", + kTTLValue, 1, kTTLValue - 1, "", 0, + IMMEDIATE_ACK_NO)); LoginClient(std::vector<std::string>()); GetFakeHandler()->ExpectOutgoingMessage(message2); PumpLoop(); @@ -460,16 +476,9 @@ TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) { // Send some messages. for (int i = 1; i <= kMessageBatchSize; ++i) { - MCSMessage message(BuildDataMessage("from", - "category", - "X", - 1, - base::IntToString(i), - kTTLValue, - 1, - 0, - "", - 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, + base::IntToString(i), kTTLValue, 1, 0, + "", 0, IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(message); mcs_client()->SendMessage(message); PumpLoop(); @@ -501,16 +510,9 @@ TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) { std::vector<std::string> id_list; for (int i = 1; i <= kMessageBatchSize; ++i) { id_list.push_back(base::IntToString(i)); - MCSMessage message(BuildDataMessage("from", - "category", - id_list.back(), - 1, - id_list.back(), - kTTLValue, - 1, - 0, - "", - 0)); + MCSMessage message(BuildDataMessage("from", "category", id_list.back(), 1, + id_list.back(), kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(message); mcs_client()->SendMessage(message); PumpLoop(); @@ -540,16 +542,9 @@ TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { std::vector<std::string> id_list; for (int i = 1; i <= kMessageBatchSize; ++i) { id_list.push_back(base::IntToString(i)); - MCSMessage message(BuildDataMessage("from", - "category", - id_list.back(), - 1, - id_list.back(), - kTTLValue, - 1, - 0, - "", - 0)); + MCSMessage message(BuildDataMessage("from", "category", id_list.back(), 1, + id_list.back(), kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(message); mcs_client()->SendMessage(message); PumpLoop(); @@ -571,16 +566,9 @@ TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { id_list.begin() + kMessageBatchSize / 2, id_list.end()); for (int i = 1; i <= kMessageBatchSize / 2; ++i) { - MCSMessage message(BuildDataMessage("from", - "category", - remaining_ids[i - 1], - 2, - remaining_ids[i - 1], - kTTLValue, - 1, - 0, - "", - 0)); + MCSMessage message(BuildDataMessage( + "from", "category", remaining_ids[i - 1], 2, remaining_ids[i - 1], + kTTLValue, 1, 0, "", 0, IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(message); } scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); @@ -600,16 +588,18 @@ TEST_F(MCSClientTest, SelectiveAckMidStream) { // Server stream id 2 ("s1"). // Acks client stream id 0 (login). - MCSMessage sMessage1(BuildDataMessage( - "from", "category", "X", 0, "s1", kTTLValue, 1, 0, "", 0)); + MCSMessage sMessage1(BuildDataMessage("from", "category", "X", 0, "s1", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ReceiveMessage(sMessage1); WaitForMCSEvent(); PumpLoop(); // Client stream id 1 ("1"). // Acks server stream id 2 ("s1"). - MCSMessage cMessage1(BuildDataMessage( - "from", "category", "Y", 2, "1", kTTLValue, 1, 0, "", 0)); + MCSMessage cMessage1(BuildDataMessage("from", "category", "Y", 2, "1", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(cMessage1); mcs_client()->SendMessage(cMessage1); PumpLoop(); @@ -618,16 +608,18 @@ TEST_F(MCSClientTest, SelectiveAckMidStream) { // Server stream id 3 ("s2"). // Acks client stream id 1 ("1"). // Confirms ack of server stream id 2 ("s1"). - MCSMessage sMessage2(BuildDataMessage( - "from", "category", "X", 1, "s2", kTTLValue, 1, 0, "", 0)); + MCSMessage sMessage2(BuildDataMessage("from", "category", "X", 1, "s2", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ReceiveMessage(sMessage2); WaitForMCSEvent(); PumpLoop(); // Client Stream id 2 ("2"). // Acks server stream id 3 ("s2"). - MCSMessage cMessage2(BuildDataMessage( - "from", "category", "Y", 3, "2", kTTLValue, 1, 0, "", 0)); + MCSMessage cMessage2(BuildDataMessage("from", "category", "Y", 3, "2", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(cMessage2); mcs_client()->SendMessage(cMessage2); PumpLoop(); @@ -637,8 +629,9 @@ TEST_F(MCSClientTest, SelectiveAckMidStream) { // ack client message "1". // Client message "2" should be resent, acking server stream id 4 (selective // ack). - MCSMessage cMessage3(BuildDataMessage( - "from", "category", "Y", 4, "2", kTTLValue, 1, 0, "", 0)); + MCSMessage cMessage3(BuildDataMessage("from", "category", "Y", 4, "2", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(cMessage3); std::vector<std::string> acked_ids(1, "1"); scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); @@ -658,8 +651,9 @@ TEST_F(MCSClientTest, SelectiveAckMidStream) { acked_ids[0] = "s2"; LoginClient(acked_ids); - MCSMessage cMessage4(BuildDataMessage( - "from", "category", "Y", 1, "2", kTTLValue, 1, 0, "", 0)); + MCSMessage cMessage4(BuildDataMessage("from", "category", "Y", 1, "2", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(cMessage4); PumpLoop(); EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); @@ -676,8 +670,9 @@ TEST_F(MCSClientTest, AckOnLogin) { std::vector<std::string> id_list; for (int i = 1; i <= kMessageBatchSize; ++i) { id_list.push_back(base::IntToString(i)); - MCSMessage message(BuildDataMessage( - "from", "category", "X", 1, id_list.back(), kTTLValue, 1, 0, "", 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, + id_list.back(), kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ReceiveMessage(message); WaitForMCSEvent(); PumpLoop(); @@ -701,31 +696,17 @@ TEST_F(MCSClientTest, AckOnSend) { std::vector<std::string> id_list; for (int i = 1; i <= kMessageBatchSize; ++i) { id_list.push_back(base::IntToString(i)); - MCSMessage message(BuildDataMessage("from", - "category", - id_list.back(), - 1, - id_list.back(), - kTTLValue, - 1, - 0, - "", - 0)); + MCSMessage message(BuildDataMessage("from", "category", id_list.back(), 1, + id_list.back(), kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ReceiveMessage(message); PumpLoop(); } // Trigger a message send, which should acknowledge via stream ack. - MCSMessage message(BuildDataMessage("from", - "category", - "X", - kMessageBatchSize + 1, - "1", - kTTLValue, - 1, - 0, - "", - 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", + kMessageBatchSize + 1, "1", kTTLValue, 1, + 0, "", 0, IMMEDIATE_ACK_NO)); GetFakeHandler()->ExpectOutgoingMessage(message); mcs_client()->SendMessage(message); EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); @@ -747,16 +728,9 @@ TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { std::vector<std::string> id_list; for (int i = 1; i <= kAckLimitSize; ++i) { id_list.push_back(base::IntToString(i)); - MCSMessage message(BuildDataMessage("from", - "category", - id_list.back(), - 1, - id_list.back(), - kTTLValue, - 1, - 0, - "", - 0)); + MCSMessage message(BuildDataMessage("from", "category", id_list.back(), 1, + id_list.back(), kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); GetFakeHandler()->ReceiveMessage(message); WaitForMCSEvent(); PumpLoop(); @@ -793,8 +767,9 @@ TEST_F(MCSClientTest, ExpiredTTLOnSend) { BuildMCSClient(); InitializeClient(); LoginClient(std::vector<std::string>()); - MCSMessage message(BuildDataMessage( - "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, "1", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); // Advance time to after the TTL. clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); @@ -812,8 +787,9 @@ TEST_F(MCSClientTest, ExpiredTTLOnRestart) { InitializeClient(); LoginClient(std::vector<std::string>()); GetFakeHandler()->set_fail_send(true); - MCSMessage message(BuildDataMessage( - "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); + MCSMessage message(BuildDataMessage("from", "category", "X", 1, "1", + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); // The initial (failed) send. GetFakeHandler()->ExpectOutgoingMessage(message); @@ -840,12 +816,14 @@ TEST_F(MCSClientTest, ExpiredTTLOnRestart) { TEST_F(MCSClientTest, CollapseKeysSameApp) { BuildMCSClient(); InitializeClient(); - MCSMessage message(BuildDataMessage( - "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); + MCSMessage message(BuildDataMessage("from", "app", "message id 1", 1, "1", + kTTLValue, 1, 0, "token", 0, + IMMEDIATE_ACK_NO)); mcs_client()->SendMessage(message); - MCSMessage message2(BuildDataMessage( - "from", "app", "message id 2", 1, "1", kTTLValue, 1, 0, "token", 0)); + MCSMessage message2(BuildDataMessage("from", "app", "message id 2", 1, "1", + kTTLValue, 1, 0, "token", 0, + IMMEDIATE_ACK_NO)); mcs_client()->SendMessage(message2); LoginClient(std::vector<std::string>()); @@ -858,20 +836,14 @@ TEST_F(MCSClientTest, CollapseKeysSameApp) { TEST_F(MCSClientTest, CollapseKeysDifferentApp) { BuildMCSClient(); InitializeClient(); - MCSMessage message(BuildDataMessage( - "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); + MCSMessage message(BuildDataMessage("from", "app", "message id 1", 1, "1", + kTTLValue, 1, 0, "token", 0, + IMMEDIATE_ACK_NO)); mcs_client()->SendMessage(message); - MCSMessage message2(BuildDataMessage("from", - "app 2", - "message id 2", - 1, - "2", - kTTLValue, - 1, - 0, - "token", - 0)); + MCSMessage message2(BuildDataMessage("from", "app 2", "message id 2", 1, "2", + kTTLValue, 1, 0, "token", 0, + IMMEDIATE_ACK_NO)); mcs_client()->SendMessage(message2); LoginClient(std::vector<std::string>()); @@ -885,20 +857,14 @@ TEST_F(MCSClientTest, CollapseKeysDifferentApp) { TEST_F(MCSClientTest, CollapseKeysDifferentUser) { BuildMCSClient(); InitializeClient(); - MCSMessage message(BuildDataMessage( - "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); + MCSMessage message(BuildDataMessage("from", "app", "message id 1", 1, "1", + kTTLValue, 1, 0, "token", 0, + IMMEDIATE_ACK_NO)); mcs_client()->SendMessage(message); - MCSMessage message2(BuildDataMessage("from", - "app", - "message id 2", - 1, - "2", - kTTLValue, - 1, - 0, - "token", - 1)); + MCSMessage message2(BuildDataMessage("from", "app", "message id 2", 1, "2", + kTTLValue, 1, 0, "token", 1, + IMMEDIATE_ACK_NO)); mcs_client()->SendMessage(message2); LoginClient(std::vector<std::string>()); @@ -1175,6 +1141,42 @@ TEST_F(MCSClientTest, CustomHeartbeatIntervalRemoveShorterInterval) { EXPECT_EQ(interval_ms, hb_manager->GetClientHeartbeatIntervalMs()); } +// Receive a message with immediate ack request, which should trigger an +// automatic stream ack. +TEST_F(MCSClientTest, AckWhenImmediateAckRequested) { + BuildMCSClient(); + InitializeClient(); + LoginClient(std::vector<std::string>()); + + // The stream ack. + scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); + ack->set_last_stream_id_received(kAckLimitSize - 1); + GetFakeHandler()->ExpectOutgoingMessage(MCSMessage(kIqStanzaTag, ack.Pass())); + + // Receive some messages. + for (int i = 1; i < kAckLimitSize - 2; ++i) { + std::string id(base::IntToString(i)); + MCSMessage message(BuildDataMessage("from", "category", id, 1, id, + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_NO)); + GetFakeHandler()->ReceiveMessage(message); + WaitForMCSEvent(); + PumpLoop(); + } + // This message expects immediate ACK, which means it will happen before the + // ACK limit size is reached. All of the preceding messages will be acked at + // the same time. + std::string ack_id(base::IntToString(kAckLimitSize - 1)); + MCSMessage message(BuildDataMessage("from", "category", ack_id, 1, ack_id, + kTTLValue, 1, 0, "", 0, + IMMEDIATE_ACK_YES)); + GetFakeHandler()->ReceiveMessage(message); + WaitForMCSEvent(); + PumpLoop(); + + EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); +} + } // namespace } // namespace gcm diff --git a/google_apis/gcm/protocol/mcs.proto b/google_apis/gcm/protocol/mcs.proto index a1ea614..cba5845 100644 --- a/google_apis/gcm/protocol/mcs.proto +++ b/google_apis/gcm/protocol/mcs.proto @@ -253,6 +253,22 @@ message DataMessageStanza { // Optional field containing the binary payload of the message. optional bytes raw_data = 21; + + // Not used. + // The maximum delay of the message, in seconds. + // optional int32 max_delay = 22; + + // Not used. + // How long the message was delayed before it was sent, in seconds. + // optional int32 actual_delay = 23; + + // If set the server requests immediate ack. Used for important messages and + // for testing. + optional bool immediate_ack = 24; + + // Not used. + // Enables message receipts from MCS/GCM back to CCS clients + // optional bool delivery_receipt_requested = 25; } /** |