Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Side by Side Diff: components/gcm_driver/gcm_client_impl.cc

Issue 2578583002: Provide a mechanism for the GCM driver to send message receipts to GCM.
Patch Set: Added a callback entry point to GCMDriver, moved MessageReceiptCallback to gcm_message_status. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/gcm_driver/gcm_client_impl.h" 5 #include "components/gcm_driver/gcm_client_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
18 #include "base/sequenced_task_runner.h" 18 #include "base/sequenced_task_runner.h"
19 #include "base/single_thread_task_runner.h" 19 #include "base/single_thread_task_runner.h"
20 #include "base/stl_util.h" 20 #include "base/stl_util.h"
21 #include "base/strings/string_number_conversions.h" 21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
23 #include "base/threading/thread_task_runner_handle.h" 23 #include "base/threading/thread_task_runner_handle.h"
24 #include "base/time/default_clock.h" 24 #include "base/time/default_clock.h"
25 #include "base/time/time.h"
25 #include "base/timer/timer.h" 26 #include "base/timer/timer.h"
26 #include "components/crx_file/id_util.h" 27 #include "components/crx_file/id_util.h"
27 #include "components/gcm_driver/gcm_account_mapper.h" 28 #include "components/gcm_driver/gcm_account_mapper.h"
28 #include "components/gcm_driver/gcm_backoff_policy.h" 29 #include "components/gcm_driver/gcm_backoff_policy.h"
30 #include "components/gcm_driver/gcm_message_status.h"
29 #include "google_apis/gcm/base/encryptor.h" 31 #include "google_apis/gcm/base/encryptor.h"
30 #include "google_apis/gcm/base/mcs_message.h" 32 #include "google_apis/gcm/base/mcs_message.h"
31 #include "google_apis/gcm/base/mcs_util.h" 33 #include "google_apis/gcm/base/mcs_util.h"
32 #include "google_apis/gcm/engine/checkin_request.h" 34 #include "google_apis/gcm/engine/checkin_request.h"
33 #include "google_apis/gcm/engine/connection_factory_impl.h" 35 #include "google_apis/gcm/engine/connection_factory_impl.h"
34 #include "google_apis/gcm/engine/gcm_registration_request_handler.h" 36 #include "google_apis/gcm/engine/gcm_registration_request_handler.h"
35 #include "google_apis/gcm/engine/gcm_store_impl.h" 37 #include "google_apis/gcm/engine/gcm_store_impl.h"
36 #include "google_apis/gcm/engine/gcm_unregistration_request_handler.h" 38 #include "google_apis/gcm/engine/gcm_unregistration_request_handler.h"
37 #include "google_apis/gcm/engine/instance_id_delete_token_request_handler.h" 39 #include "google_apis/gcm/engine/instance_id_delete_token_request_handler.h"
38 #include "google_apis/gcm/engine/instance_id_get_token_request_handler.h" 40 #include "google_apis/gcm/engine/instance_id_get_token_request_handler.h"
39 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" 41 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
40 #include "google_apis/gcm/protocol/checkin.pb.h" 42 #include "google_apis/gcm/protocol/checkin.pb.h"
41 #include "google_apis/gcm/protocol/mcs.pb.h" 43 #include "google_apis/gcm/protocol/mcs.pb.h"
42 #include "net/http/http_network_session.h" 44 #include "net/http/http_network_session.h"
43 #include "net/http/http_transaction_factory.h" 45 #include "net/http/http_transaction_factory.h"
44 #include "net/url_request/url_request_context.h" 46 #include "net/url_request/url_request_context.h"
45 #include "url/gurl.h" 47 #include "url/gurl.h"
46 48
47 namespace gcm { 49 namespace gcm {
48 50
49 namespace { 51 namespace {
50 52
53 const char kGcmMessageTypeKey[] = "type";
54 const char kMessageReceiptType[] = "message_receipt";
55 const char kReceiptMessageIdKey[] = "message_id";
56 const char kReceiptStatusKey[] = "status";
57 // kReceiptGCMDestinationID is the destination ID which GCM listens to for
58 // upstream receipt messages.
59 const char kReceiptGCMDestinationID[] = "1029510549786@google.com";
60 const int kReceiptTTLInSeconds = 10;
Peter Beverloo 2017/02/08 17:09:09 micro nit: unify with the constant block around li
harkness 2017/02/09 16:27:29 Done.
61
51 // Indicates a message type of the received message. 62 // Indicates a message type of the received message.
52 enum MessageType { 63 enum MessageType {
53 UNKNOWN, // Undetermined type. 64 UNKNOWN, // Undetermined type.
54 DATA_MESSAGE, // Regular data message. 65 DATA_MESSAGE, // Regular data message.
55 DELETED_MESSAGES, // Messages were deleted on the server. 66 DELETED_MESSAGES, // Messages were deleted on the server.
56 SEND_ERROR, // Error sending a message. 67 SEND_ERROR, // Error sending a message.
57 }; 68 };
58 69
59 enum OutgoingMessageTTLCategory { 70 enum OutgoingMessageTTLCategory {
60 TTL_ZERO, 71 TTL_ZERO,
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 HandleIncomingDataMessage(app_id, use_subtype, data_message_stanza, 1346 HandleIncomingDataMessage(app_id, use_subtype, data_message_stanza,
1336 message_data); 1347 message_data);
1337 break; 1348 break;
1338 case DELETED_MESSAGES: 1349 case DELETED_MESSAGES:
1339 HandleIncomingDeletedMessages(app_id, data_message_stanza, message_data); 1350 HandleIncomingDeletedMessages(app_id, data_message_stanza, message_data);
1340 break; 1351 break;
1341 case SEND_ERROR: 1352 case SEND_ERROR:
1342 HandleIncomingSendError(app_id, data_message_stanza, message_data); 1353 HandleIncomingSendError(app_id, data_message_stanza, message_data);
1343 break; 1354 break;
1344 case UNKNOWN: 1355 case UNKNOWN:
1356 SendMessageReceipt(data_message_stanza.id(), app_id,
1357 GCMMessageStatus::GCM_UNKNOWN_MESSAGE_TYPE);
1345 DVLOG(1) << "Unknown message_type received. Message ignored. " 1358 DVLOG(1) << "Unknown message_type received. Message ignored. "
1346 << "App ID: " << app_id << "."; 1359 << "App ID: " << app_id << ".";
1347 break; 1360 break;
1348 } 1361 }
1349 } 1362 }
1350 1363
1351 void GCMClientImpl::HandleIncomingDataMessage( 1364 void GCMClientImpl::HandleIncomingDataMessage(
1352 const std::string& app_id, 1365 const std::string& app_id,
1353 bool was_subtype, 1366 bool was_subtype,
1354 const mcs_proto::DataMessageStanza& data_message_stanza, 1367 const mcs_proto::DataMessageStanza& data_message_stanza,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 if (registered) { 1416 if (registered) {
1404 UMA_HISTOGRAM_BOOLEAN("GCM.DataMessageReceived", true); 1417 UMA_HISTOGRAM_BOOLEAN("GCM.DataMessageReceived", true);
1405 bool has_collapse_key = 1418 bool has_collapse_key =
1406 data_message_stanza.has_token() && !data_message_stanza.token().empty(); 1419 data_message_stanza.has_token() && !data_message_stanza.token().empty();
1407 UMA_HISTOGRAM_BOOLEAN("GCM.DataMessageReceivedHasCollapseKey", 1420 UMA_HISTOGRAM_BOOLEAN("GCM.DataMessageReceivedHasCollapseKey",
1408 has_collapse_key); 1421 has_collapse_key);
1409 } 1422 }
1410 recorder_.RecordDataMessageReceived(app_id, sender, 1423 recorder_.RecordDataMessageReceived(app_id, sender,
1411 data_message_stanza.ByteSize(), registered, 1424 data_message_stanza.ByteSize(), registered,
1412 GCMStatsRecorder::DATA_MESSAGE); 1425 GCMStatsRecorder::DATA_MESSAGE);
1413 if (!registered) 1426 if (!registered) {
1427 SendMessageReceipt(data_message_stanza.id(), app_id,
1428 GCMMessageStatus::GCM_INVALID_SUBTYPE);
Peter Beverloo 2017/02/08 17:09:09 INVALID_SUBTYPE is not really accurate - INVALID_R
harkness 2017/02/09 16:27:30 Thanks for reminding me, I was planning to rewrite
1414 return; 1429 return;
1430 }
1415 1431
1416 IncomingMessage incoming_message; 1432 IncomingMessage incoming_message;
1417 incoming_message.sender_id = data_message_stanza.from(); 1433 incoming_message.sender_id = data_message_stanza.from();
1418 if (data_message_stanza.has_token()) 1434 if (data_message_stanza.has_token())
1419 incoming_message.collapse_key = data_message_stanza.token(); 1435 incoming_message.collapse_key = data_message_stanza.token();
1420 incoming_message.data = message_data; 1436 incoming_message.data = message_data;
1421 incoming_message.raw_data = data_message_stanza.raw_data(); 1437 incoming_message.raw_data = data_message_stanza.raw_data();
1422 1438
1423 delegate_->OnMessageReceived(app_id, incoming_message); 1439 // Pass the message up to the GCMDriver. Also pass a callback which will send
1440 // a receipt for this message if invoked with a message status.
1441 delegate_->OnMessageReceived(app_id, incoming_message,
1442 base::Bind(&GCMClientImpl::SendMessageReceipt,
1443 weak_ptr_factory_.GetWeakPtr(),
1444 data_message_stanza.id(), app_id));
1424 } 1445 }
1425 1446
1426 void GCMClientImpl::HandleIncomingDeletedMessages( 1447 void GCMClientImpl::HandleIncomingDeletedMessages(
1427 const std::string& app_id, 1448 const std::string& app_id,
1428 const mcs_proto::DataMessageStanza& data_message_stanza, 1449 const mcs_proto::DataMessageStanza& data_message_stanza,
1429 MessageData& message_data) { 1450 MessageData& message_data) {
1430 int deleted_count = 0; 1451 int deleted_count = 0;
1431 MessageData::iterator count_iter = message_data.find(kDeletedCountKey); 1452 MessageData::iterator count_iter = message_data.find(kDeletedCountKey);
1432 if (count_iter != message_data.end()) { 1453 if (count_iter != message_data.end()) {
1433 if (!base::StringToInt(count_iter->second, &deleted_count)) 1454 if (!base::StringToInt(count_iter->second, &deleted_count))
(...skipping 30 matching lines...) Expand all
1464 1485
1465 bool GCMClientImpl::HasStandaloneRegisteredApp() const { 1486 bool GCMClientImpl::HasStandaloneRegisteredApp() const {
1466 if (registrations_.empty()) 1487 if (registrations_.empty())
1467 return false; 1488 return false;
1468 // Note that account mapper is not counted as a standalone app since it is 1489 // Note that account mapper is not counted as a standalone app since it is
1469 // automatically started when other app uses GCM. 1490 // automatically started when other app uses GCM.
1470 return registrations_.size() > 1 || 1491 return registrations_.size() > 1 ||
1471 !ExistsGCMRegistrationInMap(registrations_, kGCMAccountMapperAppId); 1492 !ExistsGCMRegistrationInMap(registrations_, kGCMAccountMapperAppId);
1472 } 1493 }
1473 1494
1495 void GCMClientImpl::SendMessageReceipt(const std::string& message_id,
1496 const std::string& app_id,
1497 GCMMessageStatus status) {
1498 DCHECK(!app_id.empty());
Peter Beverloo 2017/02/08 17:09:09 Could |app_id| (or |message_id|, which should get
harkness 2017/02/09 16:27:30 There are checks in some of the GCMDriver code, bu
1499
1500 // Prepare a message to send to GCM which will log the status of the received
Peter Beverloo 2017/02/08 17:09:09 What do you think about guarding this behind a fin
harkness 2017/02/09 16:27:29 Sounds like a good idea. I'll upload the patch set
1501 // message. This is aggregated by GCM to provide better error alerting.
1502 OutgoingMessage message;
1503 message.time_to_live = kReceiptTTLInSeconds;
1504 message.id =
1505 base::Int64ToString(base::Time::NowFromSystemTime().ToInternalValue());
Peter Beverloo 2017/02/08 17:09:09 How was this decided? base::Time stores millisecon
harkness 2017/02/09 16:27:30 I'm using the time because that's the way GCMClien
1506 message.data[kGcmMessageTypeKey] = kMessageReceiptType;
1507 message.data[kReceiptMessageIdKey] = message_id;
1508 message.data[kReceiptStatusKey] = base::IntToString(static_cast<int>(status));
1509
1510 Send(app_id, kReceiptGCMDestinationID, message);
1511 }
1512
1474 } // namespace gcm 1513 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698