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.
4
5 #include "chrome/browser/ui/webui/gcm_internals_ui.h"
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/macros.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/values.h"
15 #include "chrome/browser/gcm/gcm_profile_service_factory.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/url_constants.h"
18 #include "components/gcm_driver/gcm_client.h"
19 #include "components/gcm_driver/gcm_driver.h"
20 #include "components/gcm_driver/gcm_internals_constants.h"
21 #include "components/gcm_driver/gcm_internals_helper.h"
22 #include "components/gcm_driver/gcm_profile_service.h"
23 #include "components/grit/dev_ui_components_resources.h"
24 #include "content/public/browser/web_ui.h"
25 #include "content/public/browser/web_ui_controller.h"
26 #include "content/public/browser/web_ui_data_source.h"
27 #include "content/public/browser/web_ui_message_handler.h"
28
29 namespace {
30
31 // Class acting as a controller of the chrome://gcm-internals WebUI.
32 class GcmInternalsUIMessageHandler : public content::WebUIMessageHandler {
33 public:
34 GcmInternalsUIMessageHandler();
35 ~GcmInternalsUIMessageHandler() override;
36
37 // WebUIMessageHandler implementation.
38 void RegisterMessages() override;
39
40 private:
41 // Return all of the GCM related infos to the gcm-internals page by calling
42 // Javascript callback function
43 // |gcm-internals.returnInfo()|.
44 void ReturnResults(Profile* profile, gcm::GCMProfileService* profile_service,
45 const gcm::GCMClient::GCMStatistics* stats) const;
46
47 // Request all of the GCM related infos through gcm profile service.
48 void RequestAllInfo(const base::ListValue* args);
49
50 // Enables/disables GCM activity recording through gcm profile service.
51 void SetRecording(const base::ListValue* args);
52
53 // Callback function of the request for all gcm related infos.
54 void RequestGCMStatisticsFinished(
55 const gcm::GCMClient::GCMStatistics& args) const;
56
57 // Factory for creating references in callbacks.
58 base::WeakPtrFactory<GcmInternalsUIMessageHandler> weak_ptr_factory_{this};
59
60 DISALLOW_COPY_AND_ASSIGN(GcmInternalsUIMessageHandler);
61 };
62
GcmInternalsUIMessageHandler()63 GcmInternalsUIMessageHandler::GcmInternalsUIMessageHandler() {}
64
~GcmInternalsUIMessageHandler()65 GcmInternalsUIMessageHandler::~GcmInternalsUIMessageHandler() {}
66
ReturnResults(Profile * profile,gcm::GCMProfileService * profile_service,const gcm::GCMClient::GCMStatistics * stats) const67 void GcmInternalsUIMessageHandler::ReturnResults(
68 Profile* profile,
69 gcm::GCMProfileService* profile_service,
70 const gcm::GCMClient::GCMStatistics* stats) const {
71 base::DictionaryValue results;
72 gcm_driver::SetGCMInternalsInfo(stats, profile_service, profile->GetPrefs(),
73 &results);
74 web_ui()->CallJavascriptFunctionUnsafe(gcm_driver::kSetGcmInternalsInfo,
75 results);
76 }
77
RequestAllInfo(const base::ListValue * args)78 void GcmInternalsUIMessageHandler::RequestAllInfo(
79 const base::ListValue* args) {
80 if (args->GetSize() != 1) {
81 NOTREACHED();
82 return;
83 }
84 bool clear_logs = false;
85 if (!args->GetBoolean(0, &clear_logs)) {
86 NOTREACHED();
87 return;
88 }
89
90 gcm::GCMDriver::ClearActivityLogs clear_activity_logs =
91 clear_logs ? gcm::GCMDriver::CLEAR_LOGS : gcm::GCMDriver::KEEP_LOGS;
92
93 Profile* profile = Profile::FromWebUI(web_ui());
94 gcm::GCMProfileService* profile_service =
95 gcm::GCMProfileServiceFactory::GetForProfile(profile);
96
97 if (!profile_service || !profile_service->driver()) {
98 ReturnResults(profile, NULL, NULL);
99 } else {
100 profile_service->driver()->GetGCMStatistics(
101 base::Bind(&GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished,
102 weak_ptr_factory_.GetWeakPtr()),
103 clear_activity_logs);
104 }
105 }
106
SetRecording(const base::ListValue * args)107 void GcmInternalsUIMessageHandler::SetRecording(const base::ListValue* args) {
108 if (args->GetSize() != 1) {
109 NOTREACHED();
110 return;
111 }
112 bool recording = false;
113 if (!args->GetBoolean(0, &recording)) {
114 NOTREACHED();
115 return;
116 }
117
118 Profile* profile = Profile::FromWebUI(web_ui());
119 gcm::GCMProfileService* profile_service =
120 gcm::GCMProfileServiceFactory::GetForProfile(profile);
121
122 if (!profile_service) {
123 ReturnResults(profile, NULL, NULL);
124 return;
125 }
126 // Get fresh stats after changing recording setting.
127 profile_service->driver()->SetGCMRecording(
128 base::Bind(
129 &GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished,
130 weak_ptr_factory_.GetWeakPtr()),
131 recording);
132 }
133
RequestGCMStatisticsFinished(const gcm::GCMClient::GCMStatistics & stats) const134 void GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished(
135 const gcm::GCMClient::GCMStatistics& stats) const {
136 Profile* profile = Profile::FromWebUI(web_ui());
137 DCHECK(profile);
138 gcm::GCMProfileService* profile_service =
139 gcm::GCMProfileServiceFactory::GetForProfile(profile);
140 DCHECK(profile_service);
141 ReturnResults(profile, profile_service, &stats);
142 }
143
RegisterMessages()144 void GcmInternalsUIMessageHandler::RegisterMessages() {
145 web_ui()->RegisterMessageCallback(
146 gcm_driver::kGetGcmInternalsInfo,
147 base::BindRepeating(&GcmInternalsUIMessageHandler::RequestAllInfo,
148 weak_ptr_factory_.GetWeakPtr()));
149 web_ui()->RegisterMessageCallback(
150 gcm_driver::kSetGcmInternalsRecording,
151 base::BindRepeating(&GcmInternalsUIMessageHandler::SetRecording,
152 weak_ptr_factory_.GetWeakPtr()));
153 }
154
155 } // namespace
156
GCMInternalsUI(content::WebUI * web_ui)157 GCMInternalsUI::GCMInternalsUI(content::WebUI* web_ui)
158 : content::WebUIController(web_ui) {
159 // Set up the chrome://gcm-internals source.
160 content::WebUIDataSource* html_source =
161 content::WebUIDataSource::Create(chrome::kChromeUIGCMInternalsHost);
162
163 html_source->UseStringsJs();
164
165 // Add required resources.
166 html_source->AddResourcePath(gcm_driver::kGcmInternalsCSS,
167 IDR_GCM_DRIVER_GCM_INTERNALS_CSS);
168 html_source->AddResourcePath(gcm_driver::kGcmInternalsJS,
169 IDR_GCM_DRIVER_GCM_INTERNALS_JS);
170 html_source->SetDefaultResource(IDR_GCM_DRIVER_GCM_INTERNALS_HTML);
171
172 Profile* profile = Profile::FromWebUI(web_ui);
173 content::WebUIDataSource::Add(profile, html_source);
174
175 web_ui->AddMessageHandler(std::make_unique<GcmInternalsUIMessageHandler>());
176 }
177
~GCMInternalsUI()178 GCMInternalsUI::~GCMInternalsUI() {}
179