blob: 5622afe80ab70a8b3e0621422a686e52fa99faff [file]
// Copyright 2026 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/devtools/process_sharing_infobar.h"
#include <memory>
#include <string>
#include <utility>
#include "base/functional/bind.h"
#include "base/task/single_thread_task_runner.h"
#include "chrome/browser/about_flags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/infobars/browser_infobar_manager.h"
#include "chrome/browser/infobars/infobar_spec.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/grit/generated_resources.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/webui/flags/pref_service_flags_storage.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/dialog_model.h"
#include "url/gurl.h"
namespace {
void OptOutAndRestart(base::WeakPtr<content::WebContents> web_contents) {
#if BUILDFLAG(IS_CHROMEOS)
PrefService* prefs =
Profile::FromBrowserContext(web_contents->GetBrowserContext())
->GetPrefs();
#else
PrefService* prefs = g_browser_process->local_state();
#endif
// Note: Both ChromeOS owner and non-owner use PrefServiceFlagsStorage
// under the hood. OwnersFlagsStorage has additional functionalities
// for setting flags but since we are just reading the storage assume
// non-owner case and bypass asynchronous owner check.
auto flags_storage =
std::make_unique<flags_ui::PrefServiceFlagsStorage>(prefs);
about_flags::SetFeatureEntryEnabled(
flags_storage.get(),
"enable-process-per-site-up-to-main-frame-threshold@2", true);
flags_storage->CommitPendingWrites();
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, base::BindOnce(&chrome::AttemptRestart));
}
} // namespace
void ShowProcessSharingRestartDialog(content::WebContents* web_contents) {
constrained_window::ShowBrowserModal(
ui::DialogModel::Builder()
.SetInternalName("ProcessSharingAppRestart")
.AddParagraph(ui::DialogModelLabel(l10n_util::GetStringUTF16(
IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR_RESTART_NEEDED)))
.AddOkButton(
base::BindOnce(&OptOutAndRestart, web_contents->GetWeakPtr()))
.AddCancelButton(base::DoNothing())
.Build(),
web_contents->GetTopLevelNativeWindow());
}
void RegisterProcessSharingInfoBarSpec(
infobars::BrowserInfoBarManager& browser_infobar_manager) {
if (browser_infobar_manager.IsRegistered(
infobars::InfoBarDelegate::DEV_TOOLS_SHARED_PROCESS_DELEGATE)) {
return;
}
auto spec =
infobars::InfoBarSpec::Builder(
infobars::InfoBarDelegate::DEV_TOOLS_SHARED_PROCESS_DELEGATE)
.SetMessageText(
l10n_util::GetStringUTF16(IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR))
.AddOkButton(l10n_util::GetStringUTF16(
IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR_OPT_OUT),
base::BindRepeating(&ShowProcessSharingRestartDialog))
.SetLinkText(l10n_util::GetStringUTF16(
IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR_LEARN_MORE))
.SetLinkNavigationUrl(GURL(
"https://developer.chrome.com/blog/process-sharing-experiment"))
.SetScope(infobars::InfoBarScope::kTab)
.Build();
browser_infobar_manager.Register(std::move(spec));
}