Add ability to gather metrics to BubbleManager.
[chromium-blink-merge.git] / chrome / browser / ui / webui / gcm_internals_ui.cc
blob5fe318967b5ec85048effc2d268b76e93c39d91a
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/gcm_internals_ui.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/format_macros.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/values.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/services/gcm/gcm_profile_service.h"
19 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
20 #include "chrome/common/url_constants.h"
21 #include "components/gcm_driver/gcm_client.h"
22 #include "components/gcm_driver/gcm_driver.h"
23 #include "content/public/browser/web_ui.h"
24 #include "content/public/browser/web_ui_controller.h"
25 #include "content/public/browser/web_ui_data_source.h"
26 #include "content/public/browser/web_ui_message_handler.h"
27 #include "grit/browser_resources.h"
29 namespace {
31 void SetCheckinInfo(
32 const std::vector<gcm::CheckinActivity>& checkins,
33 base::ListValue* checkin_info) {
34 std::vector<gcm::CheckinActivity>::const_iterator it = checkins.begin();
35 for (; it < checkins.end(); ++it) {
36 base::ListValue* row = new base::ListValue();
37 checkin_info->Append(row);
39 row->AppendDouble(it->time.ToJsTime());
40 row->AppendString(it->event);
41 row->AppendString(it->details);
45 void SetConnectionInfo(
46 const std::vector<gcm::ConnectionActivity>& connections,
47 base::ListValue* connection_info) {
48 std::vector<gcm::ConnectionActivity>::const_iterator it = connections.begin();
49 for (; it < connections.end(); ++it) {
50 base::ListValue* row = new base::ListValue();
51 connection_info->Append(row);
53 row->AppendDouble(it->time.ToJsTime());
54 row->AppendString(it->event);
55 row->AppendString(it->details);
59 void SetRegistrationInfo(
60 const std::vector<gcm::RegistrationActivity>& registrations,
61 base::ListValue* registration_info) {
62 std::vector<gcm::RegistrationActivity>::const_iterator it =
63 registrations.begin();
64 for (; it < registrations.end(); ++it) {
65 base::ListValue* row = new base::ListValue();
66 registration_info->Append(row);
68 row->AppendDouble(it->time.ToJsTime());
69 row->AppendString(it->app_id);
70 row->AppendString(it->source);
71 row->AppendString(it->event);
72 row->AppendString(it->details);
76 void SetReceivingInfo(
77 const std::vector<gcm::ReceivingActivity>& receives,
78 base::ListValue* receive_info) {
79 std::vector<gcm::ReceivingActivity>::const_iterator it = receives.begin();
80 for (; it < receives.end(); ++it) {
81 base::ListValue* row = new base::ListValue();
82 receive_info->Append(row);
84 row->AppendDouble(it->time.ToJsTime());
85 row->AppendString(it->app_id);
86 row->AppendString(it->from);
87 row->AppendString(base::IntToString(it->message_byte_size));
88 row->AppendString(it->event);
89 row->AppendString(it->details);
93 void SetSendingInfo(
94 const std::vector<gcm::SendingActivity>& sends,
95 base::ListValue* send_info) {
96 std::vector<gcm::SendingActivity>::const_iterator it = sends.begin();
97 for (; it < sends.end(); ++it) {
98 base::ListValue* row = new base::ListValue();
99 send_info->Append(row);
101 row->AppendDouble(it->time.ToJsTime());
102 row->AppendString(it->app_id);
103 row->AppendString(it->receiver_id);
104 row->AppendString(it->message_id);
105 row->AppendString(it->event);
106 row->AppendString(it->details);
110 // Class acting as a controller of the chrome://gcm-internals WebUI.
111 class GcmInternalsUIMessageHandler : public content::WebUIMessageHandler {
112 public:
113 GcmInternalsUIMessageHandler();
114 ~GcmInternalsUIMessageHandler() override;
116 // WebUIMessageHandler implementation.
117 void RegisterMessages() override;
119 private:
120 // Return all of the GCM related infos to the gcm-internals page by calling
121 // Javascript callback function
122 // |gcm-internals.returnInfo()|.
123 void ReturnResults(Profile* profile, gcm::GCMProfileService* profile_service,
124 const gcm::GCMClient::GCMStatistics* stats) const;
126 // Request all of the GCM related infos through gcm profile service.
127 void RequestAllInfo(const base::ListValue* args);
129 // Enables/disables GCM activity recording through gcm profile service.
130 void SetRecording(const base::ListValue* args);
132 // Callback function of the request for all gcm related infos.
133 void RequestGCMStatisticsFinished(
134 const gcm::GCMClient::GCMStatistics& args) const;
136 // Factory for creating references in callbacks.
137 base::WeakPtrFactory<GcmInternalsUIMessageHandler> weak_ptr_factory_;
139 DISALLOW_COPY_AND_ASSIGN(GcmInternalsUIMessageHandler);
142 GcmInternalsUIMessageHandler::GcmInternalsUIMessageHandler()
143 : weak_ptr_factory_(this) {}
145 GcmInternalsUIMessageHandler::~GcmInternalsUIMessageHandler() {}
147 void GcmInternalsUIMessageHandler::ReturnResults(
148 Profile* profile,
149 gcm::GCMProfileService* profile_service,
150 const gcm::GCMClient::GCMStatistics* stats) const {
151 base::DictionaryValue results;
152 base::DictionaryValue* device_info = new base::DictionaryValue();
153 results.Set("deviceInfo", device_info);
155 device_info->SetBoolean("profileServiceCreated", profile_service != NULL);
156 device_info->SetBoolean("gcmEnabled",
157 gcm::GCMProfileService::IsGCMEnabled(profile));
158 if (stats) {
159 results.SetBoolean("isRecording", stats->is_recording);
160 device_info->SetBoolean("gcmClientCreated", stats->gcm_client_created);
161 device_info->SetString("gcmClientState", stats->gcm_client_state);
162 device_info->SetBoolean("connectionClientCreated",
163 stats->connection_client_created);
164 device_info->SetString("registeredAppIds",
165 base::JoinString(stats->registered_app_ids, ","));
166 if (stats->connection_client_created)
167 device_info->SetString("connectionState", stats->connection_state);
168 if (stats->android_id > 0) {
169 device_info->SetString("androidId",
170 base::StringPrintf("0x%" PRIx64, stats->android_id));
172 device_info->SetInteger("sendQueueSize", stats->send_queue_size);
173 device_info->SetInteger("resendQueueSize", stats->resend_queue_size);
175 if (stats->recorded_activities.checkin_activities.size() > 0) {
176 base::ListValue* checkin_info = new base::ListValue();
177 results.Set("checkinInfo", checkin_info);
178 SetCheckinInfo(stats->recorded_activities.checkin_activities,
179 checkin_info);
181 if (stats->recorded_activities.connection_activities.size() > 0) {
182 base::ListValue* connection_info = new base::ListValue();
183 results.Set("connectionInfo", connection_info);
184 SetConnectionInfo(stats->recorded_activities.connection_activities,
185 connection_info);
187 if (stats->recorded_activities.registration_activities.size() > 0) {
188 base::ListValue* registration_info = new base::ListValue();
189 results.Set("registrationInfo", registration_info);
190 SetRegistrationInfo(stats->recorded_activities.registration_activities,
191 registration_info);
193 if (stats->recorded_activities.receiving_activities.size() > 0) {
194 base::ListValue* receive_info = new base::ListValue();
195 results.Set("receiveInfo", receive_info);
196 SetReceivingInfo(stats->recorded_activities.receiving_activities,
197 receive_info);
199 if (stats->recorded_activities.sending_activities.size() > 0) {
200 base::ListValue* send_info = new base::ListValue();
201 results.Set("sendInfo", send_info);
202 SetSendingInfo(stats->recorded_activities.sending_activities, send_info);
205 web_ui()->CallJavascriptFunction("gcmInternals.setGcmInternalsInfo",
206 results);
209 void GcmInternalsUIMessageHandler::RequestAllInfo(
210 const base::ListValue* args) {
211 if (args->GetSize() != 1) {
212 NOTREACHED();
213 return;
215 bool clear_logs = false;
216 if (!args->GetBoolean(0, &clear_logs)) {
217 NOTREACHED();
218 return;
221 Profile* profile = Profile::FromWebUI(web_ui());
222 gcm::GCMProfileService* profile_service =
223 gcm::GCMProfileServiceFactory::GetForProfile(profile);
225 if (!profile_service || !profile_service->driver()) {
226 ReturnResults(profile, NULL, NULL);
227 } else {
228 profile_service->driver()->GetGCMStatistics(
229 base::Bind(&GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished,
230 weak_ptr_factory_.GetWeakPtr()),
231 clear_logs);
235 void GcmInternalsUIMessageHandler::SetRecording(const base::ListValue* args) {
236 if (args->GetSize() != 1) {
237 NOTREACHED();
238 return;
240 bool recording = false;
241 if (!args->GetBoolean(0, &recording)) {
242 NOTREACHED();
243 return;
246 Profile* profile = Profile::FromWebUI(web_ui());
247 gcm::GCMProfileService* profile_service =
248 gcm::GCMProfileServiceFactory::GetForProfile(profile);
250 if (!profile_service) {
251 ReturnResults(profile, NULL, NULL);
252 return;
254 // Get fresh stats after changing recording setting.
255 profile_service->driver()->SetGCMRecording(
256 base::Bind(
257 &GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished,
258 weak_ptr_factory_.GetWeakPtr()),
259 recording);
262 void GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished(
263 const gcm::GCMClient::GCMStatistics& stats) const {
264 Profile* profile = Profile::FromWebUI(web_ui());
265 DCHECK(profile);
266 gcm::GCMProfileService* profile_service =
267 gcm::GCMProfileServiceFactory::GetForProfile(profile);
268 DCHECK(profile_service);
269 ReturnResults(profile, profile_service, &stats);
272 void GcmInternalsUIMessageHandler::RegisterMessages() {
273 web_ui()->RegisterMessageCallback(
274 "getGcmInternalsInfo",
275 base::Bind(&GcmInternalsUIMessageHandler::RequestAllInfo,
276 weak_ptr_factory_.GetWeakPtr()));
277 web_ui()->RegisterMessageCallback(
278 "setGcmInternalsRecording",
279 base::Bind(&GcmInternalsUIMessageHandler::SetRecording,
280 weak_ptr_factory_.GetWeakPtr()));
283 } // namespace
285 GCMInternalsUI::GCMInternalsUI(content::WebUI* web_ui)
286 : content::WebUIController(web_ui) {
287 // Set up the chrome://gcm-internals source.
288 content::WebUIDataSource* html_source =
289 content::WebUIDataSource::Create(chrome::kChromeUIGCMInternalsHost);
291 html_source->SetJsonPath("strings.js");
293 // Add required resources.
294 html_source->AddResourcePath("gcm_internals.css", IDR_GCM_INTERNALS_CSS);
295 html_source->AddResourcePath("gcm_internals.js", IDR_GCM_INTERNALS_JS);
296 html_source->SetDefaultResource(IDR_GCM_INTERNALS_HTML);
298 Profile* profile = Profile::FromWebUI(web_ui);
299 content::WebUIDataSource::Add(profile, html_source);
301 web_ui->AddMessageHandler(new GcmInternalsUIMessageHandler());
304 GCMInternalsUI::~GCMInternalsUI() {}