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