diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd
index b1e956d8a132..02ef1ce64449 100644
--- a/app/brave_generated_resources.grd
+++ b/app/brave_generated_resources.grd
@@ -1129,6 +1129,28 @@ By installing this extension, you are agreeing to the Google Widevine Terms of U
Not now
+
+
+ Allow
+
+
+ Block
+
+
+ Send crash reports automatically so Brave can prevent this issue from happening again?
+
+
+ $1Brave Browser quit unexpectedly.
+
+
+ Brave Browser
+
+
+ You can change $1this setting again at any time.
+
+
+ this setting
+
diff --git a/app/vector_icons/BUILD.gn b/app/vector_icons/BUILD.gn
index c0179eea09b8..09542b3decdf 100644
--- a/app/vector_icons/BUILD.gn
+++ b/app/vector_icons/BUILD.gn
@@ -14,6 +14,7 @@ aggregate_vector_icons("brave_vector_icons") {
"brave_ads_close_button.icon",
"brave_ads_dark_mode_info_button.icon",
"brave_ads_light_mode_info_button.icon",
+ "brave_sad.icon",
"download_unlock.icon",
"open_in_ipfs.icon",
"open_in_tor.icon",
diff --git a/app/vector_icons/brave_sad.icon b/app/vector_icons/brave_sad.icon
new file mode 100644
index 000000000000..90a92b0af891
--- /dev/null
+++ b/app/vector_icons/brave_sad.icon
@@ -0,0 +1,50 @@
+// Copyright (c) 2021 The Brave Authors. All rights reserved.
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CANVAS_DIMENSIONS, 24,
+MOVE_TO, 22, 23,
+H_LINE_TO, 2,
+R_CUBIC_TO, -1.1f, 0, -2, -0.9f, -2, -2,
+V_LINE_TO, 3,
+R_CUBIC_TO, 0, -1.1f, 0.9f, -2, 2, -2,
+R_H_LINE_TO, 20,
+R_CUBIC_TO, 1.1f, 0, 2, 0.9f, 2, 2,
+R_V_LINE_TO, 18,
+R_CUBIC_TO, 0, 1.1f, -0.9f, 2, -2, 2,
+CLOSE,
+R_MOVE_TO, 0, -2,
+R_LINE_TO, 0, -14,
+H_LINE_TO, 2,
+R_V_LINE_TO, 14,
+R_H_LINE_TO, 20,
+CLOSE,
+MOVE_TO, 2, 3,
+R_V_LINE_TO, 2,
+R_H_LINE_TO, 20,
+V_LINE_TO, 3,
+H_LINE_TO, 2,
+CLOSE,
+R_MOVE_TO, 6.64f, 14.66f,
+R_ARC_TO, 0.99f, 0.99f, 0, 0, 1, -1.41f, -0.13f,
+R_ARC_TO, 1.03f, 1.03f, 0, 0, 1, 0.13f, -1.43f,
+R_CUBIC_TO, 1.5f, -1.27f, 3.05f, -1.92f, 4.64f, -1.92f,
+R_CUBIC_TO, 1.59f, 0, 3.14f, 0.66f, 4.64f, 1.93f,
+R_CUBIC_TO, 0.42f, 0.36f, 0.48f, 1, 0.13f, 1.43f,
+R_ARC_TO, 0.99f, 0.99f, 0, 0, 1, -1.41f, 0.13f,
+CUBIC_TO, 14.2f, 16.67f, 13.08f, 16.2f, 12, 16.2f,
+R_CUBIC_TO, -1.08f, 0, -2.2f, 0.47f, -3.36f, 1.46f,
+CLOSE,
+MOVE_TO, 9, 12.14f,
+R_CUBIC_TO, 0.55f, 0, 1, -0.45f, 1, -1.01f,
+R_CUBIC_TO, 0, -0.56f, -0.45f, -1.01f, -1, -1.01f,
+R_CUBIC_TO, -0.55f, 0, -1, 0.45f, -1, 1.01f,
+R_CUBIC_TO, 0, 0.56f, 0.45f, 1.02f, 1, 1.02f,
+CLOSE,
+R_MOVE_TO, 6, 0,
+R_CUBIC_TO, 0.55f, 0, 1, -0.45f, 1, -1.01f,
+R_CUBIC_TO, 0, -0.56f, -0.45f, -1.01f, -1, -1.01f,
+R_CUBIC_TO, -0.55f, 0, -1, 0.45f, -1, 1.01f,
+R_CUBIC_TO, 0, 0.56f, 0.45f, 1.02f, 1, 1.02f,
+CLOSE
diff --git a/browser/metrics/test/BUILD.gn b/browser/metrics/BUILD.gn
similarity index 70%
rename from browser/metrics/test/BUILD.gn
rename to browser/metrics/BUILD.gn
index a7a597606628..94213ff07cd9 100644
--- a/browser/metrics/test/BUILD.gn
+++ b/browser/metrics/BUILD.gn
@@ -10,19 +10,23 @@ import("//testing/test.gni")
source_set("brave_metrics_unit_tests") {
testonly = true
+
+ sources = [ "metrics_reporting_util_unittest.cc" ]
+ deps = [
+ "//base/test:test_support",
+ "//brave/browser",
+ "//chrome/browser",
+ "//chrome/test:test_support",
+ "//content/test:test_support",
+ ]
+
if (is_linux) {
- sources =
- [ "//brave/browser/metrics/metrics_reporting_util_unittest_linux.cc" ]
+ sources += [ "metrics_reporting_util_unittest_linux.cc" ]
+ configs += [ "//brave/build/linux:linux_channel_names" ]
- deps = [
- "//base/test:test_support",
- "//brave/browser",
- "//chrome/browser:browser",
+ deps += [
"//chrome/common:channel_info",
"//components/version_info:channel",
- "//content/test:test_support",
]
-
- configs += [ "//brave/build/linux:linux_channel_names" ]
}
}
diff --git a/browser/metrics/brave_metrics_service_accessor.cc b/browser/metrics/brave_metrics_service_accessor.cc
new file mode 100644
index 000000000000..45623d68fcf1
--- /dev/null
+++ b/browser/metrics/brave_metrics_service_accessor.cc
@@ -0,0 +1,11 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "brave/browser/metrics/brave_metrics_service_accessor.h"
+#include "chrome/browser/browser_process.h"
+
+bool BraveMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled() {
+ return IsMetricsReportingEnabled(g_browser_process->local_state());
+}
diff --git a/browser/metrics/brave_metrics_service_accessor.h b/browser/metrics/brave_metrics_service_accessor.h
new file mode 100644
index 000000000000..731b65fd81e7
--- /dev/null
+++ b/browser/metrics/brave_metrics_service_accessor.h
@@ -0,0 +1,21 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_BROWSER_METRICS_BRAVE_METRICS_SERVICE_ACCESSOR_H_
+#define BRAVE_BROWSER_METRICS_BRAVE_METRICS_SERVICE_ACCESSOR_H_
+
+#include "components/metrics/metrics_service_accessor.h"
+
+// This class limits and documents access to metrics service helper methods.
+// Since these methods are private, each user has to be explicitly declared
+// as a 'friend' below.
+class BraveMetricsServiceAccessor : public metrics::MetricsServiceAccessor {
+ private:
+ friend bool ShouldShowCrashReportPermissionAskDialog();
+
+ static bool IsMetricsAndCrashReportingEnabled();
+};
+
+#endif // BRAVE_BROWSER_METRICS_BRAVE_METRICS_SERVICE_ACCESSOR_H_
diff --git a/browser/metrics/metrics_reporting_util.cc b/browser/metrics/metrics_reporting_util.cc
index e272a6f08e42..a3c633a056ff 100644
--- a/browser/metrics/metrics_reporting_util.cc
+++ b/browser/metrics/metrics_reporting_util.cc
@@ -7,6 +7,8 @@
#include "base/logging.h"
#include "base/notreached.h"
+#include "brave/browser/metrics/brave_metrics_service_accessor.h"
+#include "chrome/browser/metrics/metrics_reporting_state.h"
#include "chrome/common/channel_info.h"
#include "components/version_info/channel.h"
@@ -25,3 +27,13 @@ bool GetDefaultPrefValueForMetricsReporting() {
return false;
}
}
+
+bool ShouldShowCrashReportPermissionAskDialog() {
+ if (IsMetricsReportingPolicyManaged())
+ return false;
+
+ if (BraveMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled())
+ return false;
+
+ return true;
+}
diff --git a/browser/metrics/metrics_reporting_util.h b/browser/metrics/metrics_reporting_util.h
index 31805a0eed3c..3d542f7e6eb9 100644
--- a/browser/metrics/metrics_reporting_util.h
+++ b/browser/metrics/metrics_reporting_util.h
@@ -7,5 +7,6 @@
#define BRAVE_BROWSER_METRICS_METRICS_REPORTING_UTIL_H_
bool GetDefaultPrefValueForMetricsReporting();
+bool ShouldShowCrashReportPermissionAskDialog();
#endif // BRAVE_BROWSER_METRICS_METRICS_REPORTING_UTIL_H_
diff --git a/browser/metrics/metrics_reporting_util_unittest.cc b/browser/metrics/metrics_reporting_util_unittest.cc
new file mode 100644
index 000000000000..bccd4bca9512
--- /dev/null
+++ b/browser/metrics/metrics_reporting_util_unittest.cc
@@ -0,0 +1,27 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include
+
+#include "brave/browser/metrics/metrics_reporting_util.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "components/metrics/metrics_pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(MetricsUtilTest, CrashReportPermissionAskDialogTest) {
+ std::unique_ptr local_state =
+ std::make_unique(
+ TestingBrowserProcess::GetGlobal());
+
+ g_browser_process->local_state()->SetBoolean(
+ metrics::prefs::kMetricsReportingEnabled, false);
+ EXPECT_TRUE(ShouldShowCrashReportPermissionAskDialog());
+
+ g_browser_process->local_state()->SetBoolean(
+ metrics::prefs::kMetricsReportingEnabled, true);
+ EXPECT_FALSE(ShouldShowCrashReportPermissionAskDialog());
+}
diff --git a/browser/sources.gni b/browser/sources.gni
index dfbd5db7a02a..d7b547ee4e4b 100644
--- a/browser/sources.gni
+++ b/browser/sources.gni
@@ -80,6 +80,8 @@ brave_chrome_browser_sources = [
"//brave/browser/browser_context_keyed_service_factories.h",
"//brave/browser/geolocation/brave_geolocation_permission_context_delegate.cc",
"//brave/browser/geolocation/brave_geolocation_permission_context_delegate.h",
+ "//brave/browser/metrics/brave_metrics_service_accessor.cc",
+ "//brave/browser/metrics/brave_metrics_service_accessor.h",
"//brave/browser/metrics/metrics_reporting_util.cc",
"//brave/browser/metrics/metrics_reporting_util.h",
"//brave/browser/update_util.cc",
diff --git a/browser/themes/theme_properties.cc b/browser/themes/theme_properties.cc
index 50d2ab31c746..bd298c15a877 100644
--- a/browser/themes/theme_properties.cc
+++ b/browser/themes/theme_properties.cc
@@ -44,6 +44,8 @@ absl::optional MaybeGetDefaultColorForBraveLightUi(int id) {
return kLightToolbarIcon;
case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_INACTIVE:
return color_utils::AlphaBlend(kLightToolbarIcon, kLightToolbar, 0.3f);
+ case BraveThemeProperties::COLOR_ICON_BASE:
+ return SkColorSetRGB(0x49, 0x50, 0x57);
#if BUILDFLAG(ENABLE_SIDEBAR)
case BraveThemeProperties::COLOR_SIDEBAR_BACKGROUND:
return SkColorSetRGB(0xF3, 0xF3, 0xF5);
@@ -128,6 +130,8 @@ absl::optional MaybeGetDefaultColorForBraveDarkUi(int id) {
return kDarkToolbarIcon;
case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_INACTIVE:
return color_utils::AlphaBlend(kDarkToolbarIcon, kDarkToolbar, 0.3f);
+ case BraveThemeProperties::COLOR_ICON_BASE:
+ return SkColorSetRGB(0xC2, 0xC4, 0xCF);
#if BUILDFLAG(ENABLE_SIDEBAR)
case BraveThemeProperties::COLOR_SIDEBAR_BACKGROUND:
return kDarkToolbar;
diff --git a/browser/themes/theme_properties.h b/browser/themes/theme_properties.h
index d7da7c54242c..bb3637dbfc69 100644
--- a/browser/themes/theme_properties.h
+++ b/browser/themes/theme_properties.h
@@ -25,6 +25,7 @@ enum TestProperty {
enum ThemeProperties {
BRAVE_THEME_PROPERTIES_START = 10000,
COLOR_BOOKMARK_BAR_INSTRUCTIONS_TEXT = BRAVE_THEME_PROPERTIES_START,
+ COLOR_ICON_BASE,
#if BUILDFLAG(ENABLE_SIDEBAR)
COLOR_SIDEBAR_ADD_BUTTON_DISABLED,
COLOR_SIDEBAR_BACKGROUND,
diff --git a/browser/ui/BUILD.gn b/browser/ui/BUILD.gn
index e1d9f8c426ac..dac1b711951b 100644
--- a/browser/ui/BUILD.gn
+++ b/browser/ui/BUILD.gn
@@ -80,6 +80,7 @@ source_set("ui") {
"content_settings/brave_content_setting_image_models.h",
"omnibox/brave_omnibox_client_impl.cc",
"omnibox/brave_omnibox_client_impl.h",
+ "session_crashed_bubble_brave.cc",
"startup/default_brave_browser_prompt.cc",
"startup/default_brave_browser_prompt.h",
"toolbar/brave_app_menu_model.cc",
@@ -132,6 +133,8 @@ source_set("ui") {
"views/brave_default_browser_dialog_view.h",
"views/brave_layout_provider.cc",
"views/brave_layout_provider.h",
+ "views/crash_report_permission_ask_dialog_view.cc",
+ "views/crash_report_permission_ask_dialog_view.h",
"views/download/brave_download_item_view.cc",
"views/download/brave_download_item_view.h",
"views/frame/brave_browser_view.cc",
@@ -542,6 +545,7 @@ source_set("ui") {
if (toolkit_views) {
deps += [
+ "//components/constrained_window",
"//ui/events",
"//ui/views",
]
diff --git a/browser/ui/browser_dialogs.h b/browser/ui/browser_dialogs.h
index 8f34abdc373a..b93e34561b2b 100644
--- a/browser/ui/browser_dialogs.h
+++ b/browser/ui/browser_dialogs.h
@@ -11,6 +11,8 @@ class Browser;
namespace brave {
void ShowDefaultBrowserDialog(Browser* browser);
+// Tab restore dialog will be launched after ask dialog is closed.
+void ShowCrashReportPermissionAskDialog(Browser* browser);
} // namespace brave
diff --git a/browser/ui/session_crashed_bubble_brave.cc b/browser/ui/session_crashed_bubble_brave.cc
new file mode 100644
index 000000000000..49f9a6e4a816
--- /dev/null
+++ b/browser/ui/session_crashed_bubble_brave.cc
@@ -0,0 +1,20 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "brave/browser/metrics/metrics_reporting_util.h"
+#include "brave/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/session_crashed_bubble.h"
+
+// static
+void SessionCrashedBubble::ShowIfNotOffTheRecordProfileBrave(Browser* browser) {
+ // If crash report permission ask dialog is launched, tab restore bubble will
+ // be shown after closing aks dialog.
+ if (ShouldShowCrashReportPermissionAskDialog()) {
+ brave::ShowCrashReportPermissionAskDialog(browser);
+ return;
+ }
+
+ ShowIfNotOffTheRecordProfile(browser);
+}
diff --git a/browser/ui/views/crash_report_permission_ask_dialog_browsertest.cc b/browser/ui/views/crash_report_permission_ask_dialog_browsertest.cc
new file mode 100644
index 000000000000..cb7fcf38ab3b
--- /dev/null
+++ b/browser/ui/views/crash_report_permission_ask_dialog_browsertest.cc
@@ -0,0 +1,36 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "brave/browser/metrics/metrics_reporting_util.h"
+#include "brave/browser/ui/brave_browser.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/ui/session_crashed_bubble.h"
+#include "chrome/browser/ui/test/test_browser_dialog.h"
+#include "components/metrics/metrics_pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/test/browser_test.h"
+
+class CrashReportPermissionAskDialogTest : public DialogBrowserTest {
+ public:
+ CrashReportPermissionAskDialogTest() = default;
+ ~CrashReportPermissionAskDialogTest() override = default;
+
+ // TestBrowserUi:
+ void ShowUi(const std::string& name) override {
+ SessionCrashedBubble::ShowIfNotOffTheRecordProfileBrave(browser());
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(CrashReportPermissionAskDialogTest, InvokeUi_Dialog) {
+ // When reporting is disabled, crash report permission ask dialog is launched.
+ g_browser_process->local_state()->SetBoolean(
+ metrics::prefs::kMetricsReportingEnabled, false);
+ ShowAndVerifyUi();
+
+ // When reporting is enabled, tab restore dialog is launched.
+ g_browser_process->local_state()->SetBoolean(
+ metrics::prefs::kMetricsReportingEnabled, true);
+ ShowAndVerifyUi();
+}
diff --git a/browser/ui/views/crash_report_permission_ask_dialog_view.cc b/browser/ui/views/crash_report_permission_ask_dialog_view.cc
new file mode 100644
index 000000000000..22c925a637b2
--- /dev/null
+++ b/browser/ui/views/crash_report_permission_ask_dialog_view.cc
@@ -0,0 +1,261 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "brave/browser/ui/views/crash_report_permission_ask_dialog_view.h"
+
+#include
+
+#include "base/bind.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "brave/app/vector_icons/vector_icons.h"
+#include "brave/browser/themes/theme_properties.h"
+#include "brave/grit/brave_generated_resources.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/metrics/metrics_reporting_state.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/session_crashed_bubble.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/common/webui_url_constants.h"
+#include "components/constrained_window/constrained_window_views.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/image_model.h"
+#include "ui/base/theme_provider.h"
+#include "ui/views/background.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/styled_label.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/layout/layout_provider.h"
+
+namespace brave {
+
+void ShowCrashReportPermissionAskDialog(Browser* browser) {
+ CrashReportPermissionAskDialogView::Show(browser);
+}
+
+} // namespace brave
+
+namespace {
+
+void ScheduleSessionCrashedBubble() {
+ // It's ok to use lastly used browser because there will be only one when
+ // this launched after un-cleaned exit.
+ if (auto* browser = BrowserList::GetInstance()->GetLastActive())
+ SessionCrashedBubble::ShowIfNotOffTheRecordProfile(browser);
+}
+
+gfx::FontList GetFont(int font_size, gfx::Font::Weight weight) {
+ gfx::FontList font_list;
+ return font_list.DeriveWithSizeDelta(font_size - font_list.GetFontSize())
+ .DeriveWithWeight(weight);
+}
+
+void OpenSettingPage() {
+ if (auto* browser = BrowserList::GetInstance()->GetLastActive())
+ chrome::ShowSettingsSubPageForProfile(browser->profile(),
+ chrome::kPrivacySubPage);
+}
+
+} // namespace
+
+// static
+void CrashReportPermissionAskDialogView::Show(Browser* browser) {
+ constrained_window::CreateBrowserModalDialogViews(
+ new CrashReportPermissionAskDialogView(browser),
+ browser->window()->GetNativeWindow())
+ ->Show();
+}
+
+CrashReportPermissionAskDialogView::CrashReportPermissionAskDialogView(
+ Browser* browser) {
+ set_should_ignore_snapping(true);
+
+ SetButtonLabel(ui::DIALOG_BUTTON_OK,
+ l10n_util::GetStringUTF16(
+ IDS_CRASH_REPORT_PERMISSION_ASK_DIALOG_OK_BUTTON_LABEL));
+ SetButtonLabel(
+ ui::DIALOG_BUTTON_CANCEL,
+ l10n_util::GetStringUTF16(
+ IDS_CRASH_REPORT_PERMISSION_ASK_DIALOG_CANCEL_BUTTON_LABEL));
+ SetAcceptCallback(
+ base::BindOnce(&CrashReportPermissionAskDialogView::OnAcceptButtonClicked,
+ base::Unretained(this)));
+ RegisterWindowClosingCallback(
+ base::BindOnce(&CrashReportPermissionAskDialogView::OnWindowClosing,
+ base::Unretained(this)));
+
+ CreateChildViews(BrowserView::GetBrowserViewForBrowser(browser)->GetWidget());
+}
+
+CrashReportPermissionAskDialogView::~CrashReportPermissionAskDialogView() =
+ default;
+
+void CrashReportPermissionAskDialogView::CreateChildViews(
+ views::Widget* parent) {
+ constexpr int kPadding = 24;
+ constexpr int kChildSpacing = 16;
+ constexpr int kIconSize = 24;
+
+ SetLayoutManager(std::make_unique(
+ views::BoxLayout::Orientation::kVertical, gfx::Insets(kPadding),
+ kChildSpacing));
+
+ // Construct header text area
+ auto* header = AddChildView(std::make_unique());
+ header->SetLayoutManager(std::make_unique(
+ views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
+ kChildSpacing));
+
+ constexpr SkColor kDefaultSadImageColor = SkColorSetRGB(0x49, 0x50, 0x57);
+ auto* header_image =
+ header->AddChildView(std::make_unique());
+ header_image->SetImageSize(gfx::Size(kIconSize, kIconSize));
+ SkColor header_image_color = kDefaultSadImageColor;
+ if (auto* theme_provider = parent->GetThemeProvider()) {
+ header_image_color =
+ theme_provider->GetColor(BraveThemeProperties::COLOR_ICON_BASE);
+ }
+ header_image->SetImage(ui::ImageModel::FromVectorIcon(
+ kBraveSadIcon, header_image_color, kIconSize));
+
+ const std::u16string header_browser_name = l10n_util::GetStringUTF16(
+ IDS_CRASH_REPORT_PERMISSION_ASK_DIALOG_HEADER_TEXT_BROWSER_NAME_PART);
+ size_t offset;
+ const std::u16string header_text = l10n_util::GetStringFUTF16(
+ IDS_CRASH_REPORT_PERMISSION_ASK_DIALOG_HEADER_TEXT, header_browser_name,
+ &offset);
+ auto* header_label =
+ header->AddChildView(std::make_unique());
+ header_label->SetText(header_text);
+
+ views::StyledLabel::RangeStyleInfo name_style;
+ name_style.custom_font = GetFont(14, gfx::Font::Weight::SEMIBOLD);
+ header_label->AddStyleRange(
+ gfx::Range(offset, offset + header_browser_name.length()), name_style);
+
+ views::StyledLabel::RangeStyleInfo default_style;
+ default_style.custom_font = GetFont(14, gfx::Font::Weight::NORMAL);
+
+ header_label->AddStyleRange(
+ gfx::Range(offset + header_browser_name.length(), header_text.length()),
+ default_style);
+ // If browser name is located in the middle of full text, apply default style
+ // all other area.
+ if (offset != 0)
+ header_label->AddStyleRange(gfx::Range(0, offset), default_style);
+
+ // Construct contents text area
+ auto* contents = AddChildView(std::make_unique());
+ contents->SetLayoutManager(std::make_unique(
+ views::BoxLayout::Orientation::kHorizontal,
+ gfx::Insets{0, kPadding + kChildSpacing, 0, 0}));
+ constexpr int kContentsTextFontSize = 13;
+ auto* contents_label = contents->AddChildView(std::make_unique(
+ l10n_util::GetStringUTF16(
+ IDS_CRASH_REPORT_PERMISSION_ASK_DIALOG_CONTENT_TEXT),
+ views::Label::CustomFont{
+ GetFont(kContentsTextFontSize, gfx::Font::Weight::NORMAL)}));
+ contents_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ contents_label->SetMultiLine(true);
+ constexpr int kContentsLabelMaxWidth = 350;
+ contents_label->SetMaximumWidth(kContentsLabelMaxWidth);
+
+ // Construct footnote text area
+ constexpr int kFootnoteVerticalPadding = 16;
+ auto* footnote = SetFootnoteView(std::make_unique());
+ auto* footnote_layout =
+ footnote->SetLayoutManager(std::make_unique(
+ views::BoxLayout::Orientation::kHorizontal,
+ gfx::Insets{kFootnoteVerticalPadding, 0}));
+ footnote_layout->set_main_axis_alignment(
+ views::BoxLayout::MainAxisAlignment::kCenter);
+ footnote->SetBackground(views::CreateThemedSolidBackground(
+ footnote, ui::NativeTheme::kColorId_DialogBackground));
+
+ const std::u16string setting_text = l10n_util::GetStringUTF16(
+ IDS_CRASH_REPORT_PERMISSION_ASK_DIALOG_FOOTNOTE_TEXT_SETTING_PART);
+ const std::u16string footnote_text = l10n_util::GetStringFUTF16(
+ IDS_CRASH_REPORT_PERMISSION_ASK_DIALOG_FOOTNOTE_TEXT, setting_text,
+ &offset);
+ auto* footnote_label =
+ footnote->AddChildView(std::make_unique());
+ footnote_label->SetHorizontalAlignment(gfx::ALIGN_CENTER);
+ footnote_label->SetText(footnote_text);
+
+ views::StyledLabel::RangeStyleInfo setting_style =
+ views::StyledLabel::RangeStyleInfo::CreateForLink(
+ base::BindRepeating(OpenSettingPage));
+ footnote_label->AddStyleRange(
+ gfx::Range(offset, offset + setting_text.length()), setting_style);
+
+ views::StyledLabel::RangeStyleInfo footnote_default_style;
+ constexpr int kFootnoteFontSize = 12;
+ footnote_default_style.custom_font =
+ GetFont(kFootnoteFontSize, gfx::Font::Weight::NORMAL);
+
+ if (offset != 0)
+ footnote_label->AddStyleRange(gfx::Range(0, offset),
+ footnote_default_style);
+
+ if (offset + setting_text.length() != footnote_text.length())
+ footnote_label->AddStyleRange(
+ gfx::Range(offset + setting_text.length(), footnote_text.length()),
+ footnote_default_style);
+}
+
+std::unique_ptr
+CrashReportPermissionAskDialogView::CreateNonClientFrameView(
+ views::Widget* widget) {
+ if (!use_custom_frame())
+ return DialogDelegateView::CreateNonClientFrameView(widget);
+
+ views::LayoutProvider* provider = views::LayoutProvider::Get();
+ auto frame = std::make_unique(
+ provider->GetInsetsMetric(views::INSETS_DIALOG_TITLE), gfx::Insets());
+
+ const views::BubbleBorder::Shadow kShadow =
+ views::BubbleBorder::DIALOG_SHADOW;
+ std::unique_ptr border =
+ std::make_unique(views::BubbleBorder::FLOAT, kShadow,
+ gfx::kPlaceholderColor);
+ border->set_use_theme_background_color(true);
+ constexpr int kCornerRadius = 16;
+ border->SetCornerRadius(kCornerRadius);
+ frame->SetFootnoteView(DisownFootnoteView());
+ frame->SetBubbleBorder(std::move(border));
+ return frame;
+}
+
+ui::ModalType CrashReportPermissionAskDialogView::GetModalType() const {
+ return ui::MODAL_TYPE_WINDOW;
+}
+
+bool CrashReportPermissionAskDialogView::ShouldShowCloseButton() const {
+ return false;
+}
+
+bool CrashReportPermissionAskDialogView::ShouldShowWindowTitle() const {
+ return false;
+}
+
+void CrashReportPermissionAskDialogView::OnDialogInitialized() {
+ SetButtonRowInsets(gfx::Insets(0, 0, 18, 24));
+}
+
+void CrashReportPermissionAskDialogView::OnAcceptButtonClicked() {
+ // Enable crash reporting.
+ ChangeMetricsReportingState(true);
+}
+
+void CrashReportPermissionAskDialogView::OnWindowClosing() {
+ // On macOS, this dialog is not destroyed properly when session crashed bubble
+ // is launched directly.
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(&ScheduleSessionCrashedBubble));
+}
diff --git a/browser/ui/views/crash_report_permission_ask_dialog_view.h b/browser/ui/views/crash_report_permission_ask_dialog_view.h
new file mode 100644
index 000000000000..03ea080ecbd8
--- /dev/null
+++ b/browser/ui/views/crash_report_permission_ask_dialog_view.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_BROWSER_UI_VIEWS_CRASH_REPORT_PERMISSION_ASK_DIALOG_VIEW_H_
+#define BRAVE_BROWSER_UI_VIEWS_CRASH_REPORT_PERMISSION_ASK_DIALOG_VIEW_H_
+
+#include
+
+#include "ui/views/window/dialog_delegate.h"
+
+class Browser;
+
+class CrashReportPermissionAskDialogView : public views::DialogDelegateView {
+ public:
+ static void Show(Browser* browser);
+
+ private:
+ explicit CrashReportPermissionAskDialogView(Browser* browser);
+ ~CrashReportPermissionAskDialogView() override;
+
+ CrashReportPermissionAskDialogView(
+ const CrashReportPermissionAskDialogView&) = delete;
+ CrashReportPermissionAskDialogView& operator=(
+ const CrashReportPermissionAskDialogView&) = delete;
+
+ // views::DialogDelegateView overrides:
+ std::unique_ptr CreateNonClientFrameView(
+ views::Widget* widget) override;
+ ui::ModalType GetModalType() const override;
+ bool ShouldShowCloseButton() const override;
+ bool ShouldShowWindowTitle() const override;
+ void OnDialogInitialized() override;
+
+ void OnAcceptButtonClicked();
+ void OnWindowClosing();
+ void CreateChildViews(views::Widget* parent);
+};
+
+#endif // BRAVE_BROWSER_UI_VIEWS_CRASH_REPORT_PERMISSION_ASK_DIALOG_VIEW_H_
diff --git a/chromium_src/chrome/browser/ui/session_crashed_bubble.h b/chromium_src/chrome/browser/ui/session_crashed_bubble.h
new file mode 100644
index 000000000000..5e71ab9d5ebe
--- /dev/null
+++ b/chromium_src/chrome/browser/ui/session_crashed_bubble.h
@@ -0,0 +1,17 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_SESSION_CRASHED_BUBBLE_H_
+#define BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_SESSION_CRASHED_BUBBLE_H_
+
+#define ShowIfNotOffTheRecordProfile \
+ ShowIfNotOffTheRecordProfileBrave(Browser* browser); \
+ static void ShowIfNotOffTheRecordProfile
+
+#include "../../../../../chrome/browser/ui/session_crashed_bubble.h"
+
+#undef ShowIfNotOffTheRecordProfile
+
+#endif // BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_SESSION_CRASHED_BUBBLE_H_
diff --git a/chromium_src/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chromium_src/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index 992520fdf958..d25839d3aa34 100644
--- a/chromium_src/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chromium_src/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -4,10 +4,12 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "brave/browser/ui/startup/default_brave_browser_prompt.h"
+#include "chrome/browser/ui/session_crashed_bubble.h"
#include "chrome/browser/ui/startup/google_api_keys_infobar_delegate.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
+#define ShowIfNotOffTheRecordProfile ShowIfNotOffTheRecordProfileBrave
#define GoogleApiKeysInfoBarDelegate BraveGoogleKeysInfoBarDelegate
class BraveGoogleKeysInfoBarDelegate {
@@ -27,3 +29,4 @@ class BraveGoogleKeysInfoBarDelegate {
#undef BRAVE_STARTUPBROWSERCREATORIMPL_DETERMINEURLSANDLAUNCH
#undef GoogleApiKeysInfoBarDelegate
#undef ShowDefaultBrowserPrompt
+#undef ShowIfNotOffTheRecordProfile
diff --git a/test/BUILD.gn b/test/BUILD.gn
index dc84b9ad319c..abd0bb7ee86d 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -151,7 +151,7 @@ test("brave_unit_tests") {
"//brave/browser/content_settings:unit_tests",
"//brave/browser/ethereum_remote_client/buildflags",
"//brave/browser/first_run:unit_tests",
- "//brave/browser/metrics/test:brave_metrics_unit_tests",
+ "//brave/browser/metrics:brave_metrics_unit_tests",
"//brave/browser/net",
"//brave/browser/new_tab:unittest",
"//brave/browser/permissions:unit_tests",
@@ -622,6 +622,7 @@ if (!is_android) {
"//brave/browser/ui/toolbar/brave_app_menu_model_browsertest.cc",
"//brave/browser/ui/views/bookmarks/bookmark_bar_browsertest.cc",
"//brave/browser/ui/views/brave_actions/brave_actions_container_browsertest.cc",
+ "//brave/browser/ui/views/crash_report_permission_ask_dialog_browsertest.cc",
"//brave/browser/ui/views/omnibox/brave_omnibox_view_views_browsertest.cc",
"//brave/browser/ui/views/omnibox/omnibox_autocomplete_browsertest.cc",
"//brave/browser/ui/views/profiles/brave_profile_menu_view_browsertest.cc",