1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/gcm_driver/gcm_internals_helper.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/format_macros.h"
11 #include "base/i18n/time_formatting.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/values.h"
17 #include "components/gcm_driver/gcm_activity.h"
18 #include "components/gcm_driver/gcm_internals_constants.h"
19 #include "components/gcm_driver/gcm_profile_service.h"
20 
21 namespace gcm_driver {
22 
23 namespace {
24 
SetCheckinInfo(const std::vector<gcm::CheckinActivity> & checkins,base::ListValue * checkin_info)25 void SetCheckinInfo(const std::vector<gcm::CheckinActivity>& checkins,
26                     base::ListValue* checkin_info) {
27   for (const gcm::CheckinActivity& checkin : checkins) {
28     auto row = std::make_unique<base::ListValue>();
29     row->AppendDouble(checkin.time.ToJsTime());
30     row->AppendString(checkin.event);
31     row->AppendString(checkin.details);
32     checkin_info->Append(std::move(row));
33   }
34 }
35 
SetConnectionInfo(const std::vector<gcm::ConnectionActivity> & connections,base::ListValue * connection_info)36 void SetConnectionInfo(const std::vector<gcm::ConnectionActivity>& connections,
37                        base::ListValue* connection_info) {
38   for (const gcm::ConnectionActivity& connection : connections) {
39     auto row = std::make_unique<base::ListValue>();
40     row->AppendDouble(connection.time.ToJsTime());
41     row->AppendString(connection.event);
42     row->AppendString(connection.details);
43     connection_info->Append(std::move(row));
44   }
45 }
46 
SetRegistrationInfo(const std::vector<gcm::RegistrationActivity> & registrations,base::ListValue * registration_info)47 void SetRegistrationInfo(
48     const std::vector<gcm::RegistrationActivity>& registrations,
49     base::ListValue* registration_info) {
50   for (const gcm::RegistrationActivity& registration : registrations) {
51     auto row = std::make_unique<base::ListValue>();
52     row->AppendDouble(registration.time.ToJsTime());
53     row->AppendString(registration.app_id);
54     row->AppendString(registration.source);
55     row->AppendString(registration.event);
56     row->AppendString(registration.details);
57     registration_info->Append(std::move(row));
58   }
59 }
60 
SetReceivingInfo(const std::vector<gcm::ReceivingActivity> & receives,base::ListValue * receive_info)61 void SetReceivingInfo(const std::vector<gcm::ReceivingActivity>& receives,
62                       base::ListValue* receive_info) {
63   for (const gcm::ReceivingActivity& receive : receives) {
64     auto row = std::make_unique<base::ListValue>();
65     row->AppendDouble(receive.time.ToJsTime());
66     row->AppendString(receive.app_id);
67     row->AppendString(receive.from);
68     row->AppendString(base::NumberToString(receive.message_byte_size));
69     row->AppendString(receive.event);
70     row->AppendString(receive.details);
71     receive_info->Append(std::move(row));
72   }
73 }
74 
SetSendingInfo(const std::vector<gcm::SendingActivity> & sends,base::ListValue * send_info)75 void SetSendingInfo(const std::vector<gcm::SendingActivity>& sends,
76                     base::ListValue* send_info) {
77   for (const gcm::SendingActivity& send : sends) {
78     auto row = std::make_unique<base::ListValue>();
79     row->AppendDouble(send.time.ToJsTime());
80     row->AppendString(send.app_id);
81     row->AppendString(send.receiver_id);
82     row->AppendString(send.message_id);
83     row->AppendString(send.event);
84     row->AppendString(send.details);
85     send_info->Append(std::move(row));
86   }
87 }
88 
SetDecryptionFailureInfo(const std::vector<gcm::DecryptionFailureActivity> & failures,base::ListValue * failure_info)89 void SetDecryptionFailureInfo(
90     const std::vector<gcm::DecryptionFailureActivity>& failures,
91     base::ListValue* failure_info) {
92   for (const gcm::DecryptionFailureActivity& failure : failures) {
93     auto row = std::make_unique<base::ListValue>();
94     row->AppendDouble(failure.time.ToJsTime());
95     row->AppendString(failure.app_id);
96     row->AppendString(failure.details);
97     failure_info->Append(std::move(row));
98   }
99 }
100 
101 }  // namespace
102 
SetGCMInternalsInfo(const gcm::GCMClient::GCMStatistics * stats,gcm::GCMProfileService * profile_service,PrefService * prefs,base::DictionaryValue * results)103 void SetGCMInternalsInfo(const gcm::GCMClient::GCMStatistics* stats,
104                          gcm::GCMProfileService* profile_service,
105                          PrefService* prefs,
106                          base::DictionaryValue* results) {
107   auto device_info = std::make_unique<base::DictionaryValue>();
108 
109   device_info->SetBoolean(kProfileServiceCreated, profile_service != nullptr);
110   device_info->SetBoolean(kGcmEnabled, true);
111   if (stats) {
112     results->SetBoolean(kIsRecording, stats->is_recording);
113     device_info->SetBoolean(kGcmClientCreated, stats->gcm_client_created);
114     device_info->SetString(kGcmClientState, stats->gcm_client_state);
115     device_info->SetBoolean(kConnectionClientCreated,
116                             stats->connection_client_created);
117 
118     auto registered_app_ids = std::make_unique<base::ListValue>();
119     for (const std::string& app_id : stats->registered_app_ids)
120       registered_app_ids->AppendString(app_id);
121 
122     device_info->SetList(kRegisteredAppIds, std::move(registered_app_ids));
123 
124     if (stats->connection_client_created)
125       device_info->SetString(kConnectionState, stats->connection_state);
126     if (!stats->last_checkin.is_null()) {
127       device_info->SetString(
128           kLastCheckin, base::UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(
129                             stats->last_checkin)));
130     }
131     if (!stats->next_checkin.is_null()) {
132       device_info->SetString(
133           kNextCheckin, base::UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(
134                             stats->next_checkin)));
135     }
136     if (stats->android_id > 0) {
137       device_info->SetString(
138           kAndroidId, base::StringPrintf("0x%" PRIx64, stats->android_id));
139     }
140     if (stats->android_secret > 0) {
141       device_info->SetString(kAndroidSecret,
142                              base::NumberToString(stats->android_secret));
143     }
144     device_info->SetInteger(kSendQueueSize, stats->send_queue_size);
145     device_info->SetInteger(kResendQueueSize, stats->resend_queue_size);
146     results->Set(kDeviceInfo, std::move(device_info));
147 
148     if (stats->recorded_activities.checkin_activities.size() > 0) {
149       auto checkin_info = std::make_unique<base::ListValue>();
150       SetCheckinInfo(stats->recorded_activities.checkin_activities,
151                      checkin_info.get());
152       results->Set(kCheckinInfo, std::move(checkin_info));
153     }
154     if (stats->recorded_activities.connection_activities.size() > 0) {
155       auto connection_info = std::make_unique<base::ListValue>();
156       SetConnectionInfo(stats->recorded_activities.connection_activities,
157                         connection_info.get());
158       results->Set(kConnectionInfo, std::move(connection_info));
159     }
160     if (stats->recorded_activities.registration_activities.size() > 0) {
161       auto registration_info = std::make_unique<base::ListValue>();
162       SetRegistrationInfo(stats->recorded_activities.registration_activities,
163                           registration_info.get());
164       results->Set(kRegistrationInfo, std::move(registration_info));
165     }
166     if (stats->recorded_activities.receiving_activities.size() > 0) {
167       auto receive_info = std::make_unique<base::ListValue>();
168       SetReceivingInfo(stats->recorded_activities.receiving_activities,
169                        receive_info.get());
170       results->Set(kReceiveInfo, std::move(receive_info));
171     }
172     if (stats->recorded_activities.sending_activities.size() > 0) {
173       auto send_info = std::make_unique<base::ListValue>();
174       SetSendingInfo(stats->recorded_activities.sending_activities,
175                      send_info.get());
176       results->Set(kSendInfo, std::move(send_info));
177     }
178 
179     if (stats->recorded_activities.decryption_failure_activities.size() > 0) {
180       auto failure_info = std::make_unique<base::ListValue>();
181       SetDecryptionFailureInfo(
182           stats->recorded_activities.decryption_failure_activities,
183           failure_info.get());
184       results->Set(kDecryptionFailureInfo, std::move(failure_info));
185     }
186   }
187 }
188 
189 }  // namespace gcm_driver
190