1 // Copyright 2013 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/chromeos/slow_ui.h"
6 
7 #include <memory>
8 #include <string>
9 
10 #include "base/bind.h"
11 #include "base/macros.h"
12 #include "base/values.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/webui/webui_util.h"
15 #include "chrome/common/pref_names.h"
16 #include "chrome/common/url_constants.h"
17 #include "chrome/grit/browser_resources.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "components/prefs/pref_change_registrar.h"
20 #include "components/prefs/pref_service.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/browser/web_ui.h"
23 #include "content/public/browser/web_ui_data_source.h"
24 #include "content/public/browser/web_ui_message_handler.h"
25 #include "ui/base/webui/jstemplate_builder.h"
26 #include "ui/base/webui/web_ui_util.h"
27 
28 using content::WebUIMessageHandler;
29 
30 namespace {
31 
32 // JS API callbacks names.
33 const char kJsApiDisableTracing[] = "disableTracing";
34 const char kJsApiEnableTracing[] = "enableTracing";
35 const char kJsApiLoadComplete[] = "loadComplete";
36 
37 // Page JS API function names.
38 const char kJsApiTracingPrefChanged[] = "options.Slow.tracingPrefChanged";
39 
40 }  // namespace
41 
42 namespace chromeos {
43 
CreateSlowUIHTMLSource()44 content::WebUIDataSource* CreateSlowUIHTMLSource() {
45   content::WebUIDataSource* source =
46       content::WebUIDataSource::Create(chrome::kChromeUISlowHost);
47 
48   static constexpr webui::LocalizedString kStrings[] = {
49       {"slowDisable", IDS_SLOW_DISABLE},
50       {"slowEnable", IDS_SLOW_ENABLE},
51       {"slowDescription", IDS_SLOW_DESCRIPTION},
52       {"slowWarning", IDS_SLOW_WARNING},
53   };
54   AddLocalizedStringsBulk(source, kStrings);
55 
56   source->AddResourcePath("slow.js", IDR_SLOW_JS);
57   source->AddResourcePath("slow.css", IDR_SLOW_CSS);
58   source->SetDefaultResource(IDR_SLOW_HTML);
59   return source;
60 }
61 
62 // The handler for Javascript messages related to the "slow" view.
63 class SlowHandler : public WebUIMessageHandler {
64  public:
65   explicit SlowHandler(Profile* profile);
66   ~SlowHandler() override;
67 
68   // WebUIMessageHandler implementation.
69   void RegisterMessages() override;
70 
71  private:
72   void UpdatePage();
73 
74   // Handlers for JS WebUI messages.
75   void HandleDisable(const base::ListValue* args);
76   void HandleEnable(const base::ListValue* args);
77   void LoadComplete(const base::ListValue* args);
78 
79   Profile* profile_;
80   std::unique_ptr<PrefChangeRegistrar> user_pref_registrar_;
81 
82   DISALLOW_COPY_AND_ASSIGN(SlowHandler);
83 };
84 
85 // SlowHandler ------------------------------------------------------------
86 
SlowHandler(Profile * profile)87 SlowHandler::SlowHandler(Profile* profile) : profile_(profile) {
88 }
89 
~SlowHandler()90 SlowHandler::~SlowHandler() {
91 }
92 
RegisterMessages()93 void SlowHandler::RegisterMessages() {
94   web_ui()->RegisterMessageCallback(
95       kJsApiDisableTracing,
96       base::BindRepeating(&SlowHandler::HandleDisable, base::Unretained(this)));
97   web_ui()->RegisterMessageCallback(
98       kJsApiEnableTracing,
99       base::BindRepeating(&SlowHandler::HandleEnable, base::Unretained(this)));
100   web_ui()->RegisterMessageCallback(
101       kJsApiLoadComplete,
102       base::BindRepeating(&SlowHandler::LoadComplete, base::Unretained(this)));
103 
104   user_pref_registrar_ = std::make_unique<PrefChangeRegistrar>();
105   user_pref_registrar_->Init(profile_->GetPrefs());
106   user_pref_registrar_->Add(prefs::kPerformanceTracingEnabled,
107                             base::Bind(&SlowHandler::UpdatePage,
108                                        base::Unretained(this)));
109 }
110 
HandleDisable(const base::ListValue * args)111 void SlowHandler::HandleDisable(const base::ListValue* args) {
112   PrefService* pref_service = profile_->GetPrefs();
113   pref_service->SetBoolean(prefs::kPerformanceTracingEnabled, false);
114 }
115 
HandleEnable(const base::ListValue * args)116 void SlowHandler::HandleEnable(const base::ListValue* args) {
117   PrefService* pref_service = profile_->GetPrefs();
118   pref_service->SetBoolean(prefs::kPerformanceTracingEnabled, true);
119 }
120 
LoadComplete(const base::ListValue * args)121 void SlowHandler::LoadComplete(const base::ListValue* args) {
122   UpdatePage();
123 }
124 
UpdatePage()125 void SlowHandler::UpdatePage() {
126   PrefService* pref_service = profile_->GetPrefs();
127   bool enabled = pref_service->GetBoolean(prefs::kPerformanceTracingEnabled);
128   base::Value pref_value(enabled);
129   web_ui()->CallJavascriptFunctionUnsafe(kJsApiTracingPrefChanged, pref_value);
130 }
131 
132 // SlowUI -----------------------------------------------------------------
133 
SlowUI(content::WebUI * web_ui)134 SlowUI::SlowUI(content::WebUI* web_ui) : WebUIController(web_ui) {
135   Profile* profile = Profile::FromWebUI(web_ui);
136 
137   web_ui->AddMessageHandler(std::make_unique<SlowHandler>(profile));
138 
139   // Set up the chrome://slow/ source.
140   content::WebUIDataSource::Add(profile, CreateSlowUIHTMLSource());
141 }
142 
143 }  // namespace chromeos
144 
145