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"
10 #include "base/bind_helpers.h"
11 #include "base/format_macros.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/values.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/services/gcm/gcm_profile_service.h"
18 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
19 #include "chrome/common/url_constants.h"
20 #include "content/public/browser/web_ui.h"
21 #include "content/public/browser/web_ui_controller.h"
22 #include "content/public/browser/web_ui_data_source.h"
23 #include "content/public/browser/web_ui_message_handler.h"
24 #include "google_apis/gcm/gcm_client.h"
25 #include "grit/browser_resources.h"
30 const std::vector
<gcm::GCMStatsRecorder::SendingActivity
>& sends
,
31 base::ListValue
* send_info
) {
32 std::vector
<gcm::GCMStatsRecorder::SendingActivity
>::const_iterator it
=
34 for (; it
< sends
.end(); ++it
) {
35 base::ListValue
* row
= new base::ListValue();
36 send_info
->Append(row
);
38 row
->AppendDouble(it
->time
.ToJsTime());
39 row
->AppendString(it
->app_id
);
40 row
->AppendString(it
->receiver_id
);
41 row
->AppendString(it
->message_id
);
42 row
->AppendString(it
->event
);
43 row
->AppendString(it
->details
);
47 // Class acting as a controller of the chrome://gcm-internals WebUI.
48 class GcmInternalsUIMessageHandler
: public content::WebUIMessageHandler
{
50 GcmInternalsUIMessageHandler();
51 virtual ~GcmInternalsUIMessageHandler();
53 // WebUIMessageHandler implementation.
54 virtual void RegisterMessages() OVERRIDE
;
57 // Return all of the GCM related infos to the gcm-internals page by calling
58 // Javascript callback function
59 // |gcm-internals.returnInfo()|.
60 void ReturnResults(Profile
* profile
, gcm::GCMProfileService
* profile_service
,
61 const gcm::GCMClient::GCMStatistics
* stats
) const;
63 // Request all of the GCM related infos through gcm profile service.
64 void RequestAllInfo(const base::ListValue
* args
);
66 // Enables/disables GCM activity recording through gcm profile service.
67 void SetRecording(const base::ListValue
* args
);
69 // Callback function of the request for all gcm related infos.
70 void RequestGCMStatisticsFinished(
71 const gcm::GCMClient::GCMStatistics
& args
) const;
73 // Factory for creating references in callbacks.
74 base::WeakPtrFactory
<GcmInternalsUIMessageHandler
> weak_ptr_factory_
;
76 DISALLOW_COPY_AND_ASSIGN(GcmInternalsUIMessageHandler
);
79 GcmInternalsUIMessageHandler::GcmInternalsUIMessageHandler()
80 : weak_ptr_factory_(this) {}
82 GcmInternalsUIMessageHandler::~GcmInternalsUIMessageHandler() {}
84 void GcmInternalsUIMessageHandler::ReturnResults(
86 gcm::GCMProfileService
* profile_service
,
87 const gcm::GCMClient::GCMStatistics
* stats
) const {
88 base::DictionaryValue results
;
89 base::DictionaryValue
* device_info
= new base::DictionaryValue();
90 results
.Set("deviceInfo", device_info
);
92 device_info
->SetBoolean("profileServiceCreated", profile_service
!= NULL
);
93 device_info
->SetString("gcmEnabledState",
94 gcm::GCMProfileService::GetGCMEnabledStateString(
95 gcm::GCMProfileService::GetGCMEnabledState(profile
)));
96 if (profile_service
) {
97 device_info
->SetString("signedInUserName",
98 profile_service
->SignedInUserName());
99 device_info
->SetBoolean("gcmClientReady",
100 profile_service
->IsGCMClientReady());
103 results
.SetBoolean("isRecording", stats
->is_recording
);
104 device_info
->SetBoolean("gcmClientCreated", stats
->gcm_client_created
);
105 device_info
->SetString("gcmClientState", stats
->gcm_client_state
);
106 device_info
->SetBoolean("connectionClientCreated",
107 stats
->connection_client_created
);
108 device_info
->SetString("registeredAppIds",
109 JoinString(stats
->registered_app_ids
, ","));
110 if (stats
->connection_client_created
)
111 device_info
->SetString("connectionState", stats
->connection_state
);
112 if (stats
->android_id
> 0) {
113 device_info
->SetString("androidId",
114 base::StringPrintf("0x%" PRIx64
, stats
->android_id
));
116 device_info
->SetInteger("sendQueueSize", stats
->send_queue_size
);
117 device_info
->SetInteger("resendQueueSize", stats
->resend_queue_size
);
119 if (stats
->recorded_activities
.sending_activities
.size() > 0) {
120 base::ListValue
* send_info
= new base::ListValue();
121 results
.Set("sendInfo", send_info
);
122 SetSendingInfo(stats
->recorded_activities
.sending_activities
, send_info
);
125 web_ui()->CallJavascriptFunction("gcmInternals.setGcmInternalsInfo",
129 void GcmInternalsUIMessageHandler::RequestAllInfo(
130 const base::ListValue
* args
) {
131 if (args
->GetSize() != 1) {
135 bool clear_logs
= false;
136 if (!args
->GetBoolean(0, &clear_logs
)) {
141 Profile
* profile
= Profile::FromWebUI(web_ui());
142 gcm::GCMProfileService
* profile_service
=
143 gcm::GCMProfileServiceFactory::GetForProfile(profile
);
145 if (!profile_service
) {
146 ReturnResults(profile
, NULL
, NULL
);
147 } else if (profile_service
->SignedInUserName().empty()) {
148 ReturnResults(profile
, profile_service
, NULL
);
150 profile_service
->GetGCMStatistics(
151 base::Bind(&GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished
,
152 weak_ptr_factory_
.GetWeakPtr()),
157 void GcmInternalsUIMessageHandler::SetRecording(const base::ListValue
* args
) {
158 if (args
->GetSize() != 1) {
162 bool recording
= false;
163 if (!args
->GetBoolean(0, &recording
)) {
168 Profile
* profile
= Profile::FromWebUI(web_ui());
169 gcm::GCMProfileService
* profile_service
=
170 gcm::GCMProfileServiceFactory::GetForProfile(profile
);
172 if (!profile_service
) {
173 ReturnResults(profile
, NULL
, NULL
);
176 if (profile_service
->SignedInUserName().empty()) {
177 ReturnResults(profile
, profile_service
, NULL
);
180 // Get fresh stats after changing recording setting.
181 profile_service
->SetGCMRecording(
183 &GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished
,
184 weak_ptr_factory_
.GetWeakPtr()),
188 void GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished(
189 const gcm::GCMClient::GCMStatistics
& stats
) const {
190 Profile
* profile
= Profile::FromWebUI(web_ui());
192 gcm::GCMProfileService
* profile_service
=
193 gcm::GCMProfileServiceFactory::GetForProfile(profile
);
194 DCHECK(profile_service
);
195 ReturnResults(profile
, profile_service
, &stats
);
198 void GcmInternalsUIMessageHandler::RegisterMessages() {
199 web_ui()->RegisterMessageCallback(
200 "getGcmInternalsInfo",
201 base::Bind(&GcmInternalsUIMessageHandler::RequestAllInfo
,
202 weak_ptr_factory_
.GetWeakPtr()));
203 web_ui()->RegisterMessageCallback(
204 "setGcmInternalsRecording",
205 base::Bind(&GcmInternalsUIMessageHandler::SetRecording
,
206 weak_ptr_factory_
.GetWeakPtr()));
211 GCMInternalsUI::GCMInternalsUI(content::WebUI
* web_ui
)
212 : content::WebUIController(web_ui
) {
213 // Set up the chrome://gcm-internals source.
214 content::WebUIDataSource
* html_source
=
215 content::WebUIDataSource::Create(chrome::kChromeUIGCMInternalsHost
);
216 html_source
->SetUseJsonJSFormatV2();
218 html_source
->SetJsonPath("strings.js");
220 // Add required resources.
221 html_source
->AddResourcePath("gcm_internals.css", IDR_GCM_INTERNALS_CSS
);
222 html_source
->AddResourcePath("gcm_internals.js", IDR_GCM_INTERNALS_JS
);
223 html_source
->SetDefaultResource(IDR_GCM_INTERNALS_HTML
);
225 Profile
* profile
= Profile::FromWebUI(web_ui
);
226 content::WebUIDataSource::Add(profile
, html_source
);
228 web_ui
->AddMessageHandler(new GcmInternalsUIMessageHandler());
231 GCMInternalsUI::~GCMInternalsUI() {}