blob: 144d4295e8d952667deeef546d6d1d9372e76ed1 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/settings/performance_handler.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/values.h"
#include "chrome/browser/feedback/show_feedback_page.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "components/performance_manager/public/features.h"
#include "components/url_matcher/url_util.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "url/gurl.h"
using content::WebContents;
namespace settings {
PerformanceHandler::PerformanceHandler() = default;
PerformanceHandler::~PerformanceHandler() = default;
void PerformanceHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"getDeviceHasBattery",
base::BindRepeating(&PerformanceHandler::HandleGetDeviceHasBattery,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"openPerformanceFeedbackDialog",
base::BindRepeating(&PerformanceHandler::HandleOpenFeedbackDialog,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"validateTabDiscardExceptionRule",
base::BindRepeating(
&PerformanceHandler::HandleValidateTabDiscardExceptionRule,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"getCurrentOpenSites",
base::BindRepeating(&PerformanceHandler::HandleGetCurrentOpenSites,
base::Unretained(this)));
}
void PerformanceHandler::OnJavascriptAllowed() {
performance_handler_observer_.Observe(
performance_manager::user_tuning::BatterySaverModeManager::GetInstance());
}
void PerformanceHandler::OnJavascriptDisallowed() {
performance_handler_observer_.Reset();
}
void PerformanceHandler::OnDeviceHasBatteryChanged(bool device_has_battery) {
DCHECK(IsJavascriptAllowed());
FireWebUIListener("device-has-battery-changed", device_has_battery);
}
base::Value PerformanceHandler::GetCurrentOpenSites() {
base::Value::List hosts;
std::set<std::pair<base::TimeTicks, std::string>, std::greater<>>
last_active_time_host_pairs;
const Profile* const profile = Profile::FromWebUI(web_ui());
ForEachCurrentBrowserWindowInterfaceOrderedByActivation(
[profile, &last_active_time_host_pairs](BrowserWindowInterface* browser) {
if (browser->GetProfile() != profile) {
return true;
}
TabStripModel* const tab_strip_model = browser->GetTabStripModel();
for (int i = 0; i < tab_strip_model->count(); ++i) {
WebContents* const web_contents =
tab_strip_model->GetWebContentsAt(i);
const GURL url = web_contents->GetLastCommittedURL();
if (url.is_valid() && url.SchemeIsHTTPOrHTTPS()) {
last_active_time_host_pairs.insert(std::make_pair(
web_contents->GetLastActiveTimeTicks(), url.GetHost()));
}
}
return true;
});
std::unordered_set<std::string> added_hosts;
for (auto& [last_active_time, host] : last_active_time_host_pairs) {
if (!base::Contains(added_hosts, host)) {
added_hosts.insert(host);
hosts.Append(host);
}
}
return base::Value(std::move(hosts));
}
void PerformanceHandler::HandleGetCurrentOpenSites(
const base::Value::List& args) {
CHECK_EQ(1U, args.size());
const base::Value& callback_id = args[0];
AllowJavascript();
ResolveJavascriptCallback(callback_id, GetCurrentOpenSites());
}
void PerformanceHandler::HandleGetDeviceHasBattery(
const base::Value::List& args) {
CHECK_EQ(1U, args.size());
const base::Value& callback_id = args[0];
AllowJavascript();
ResolveJavascriptCallback(
callback_id, base::Value(performance_manager::user_tuning::
BatterySaverModeManager::GetInstance()
->DeviceHasBattery()));
}
void PerformanceHandler::HandleOpenFeedbackDialog(
const base::Value::List& args) {
CHECK_EQ(1U, args.size());
const std::string category_tag = args[0].GetString();
Browser* browser = chrome::FindBrowserWithTab(web_ui()->GetWebContents());
DCHECK(browser);
std::string unused;
chrome::ShowFeedbackPage(browser,
feedback::kFeedbackSourceSettingsPerformancePage,
unused, unused, category_tag, unused);
}
void PerformanceHandler::HandleValidateTabDiscardExceptionRule(
const base::Value::List& args) {
CHECK_EQ(2U, args.size());
const base::Value& callback_id = args[0];
const std::string rule = args[1].GetString();
AllowJavascript();
url_matcher::util::FilterComponents components;
bool is_valid = url_matcher::util::FilterToComponents(
rule, &components.scheme, &components.host, &components.match_subdomains,
&components.port, &components.path, &components.query);
ResolveJavascriptCallback(callback_id, base::Value(is_valid));
}
} // namespace settings