Commit 4e425ce4 authored by Elly Fong-Jones's avatar Elly Fong-Jones Committed by Commit Bot

mac: introduce system infobar

This infobar will be used (via field trials) to display updated info
about current OS support and provide users with a link to more info.
The infobar receives both activation info (which configs to show for)
and the actual strings to display via field trials, so it can be updated
for deployed Chrome instances without an update cycle.

This change adds:
* The infobar itself
* A feature MacSystemInfobar that controls whether the feature is
  enabled and if so which configs (Arm or Rosetta) it's enabled in
* A switch --force-mac-system-infobar which causes the infobar to act as
  though it was running on a specified system, for both manual and
  automatic tests
* A variety of IDS_MAC_SYSTEM_INFOBAR_* constants to customize the
  infobar's message, link, and link text
* Unit tests for the logic to interpret the feature and the
  enable/disable configs

Bug: 1116578
Change-Id: Ie7fd6e772a0112a17e794d1b8fcb009c57ebed4a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2360479
Commit-Queue: Elly Fong-Jones <ellyjones@chromium.org>
Reviewed-by: default avatarAlexei Svitkine <asvitkine@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799615}
parent 4da55b37
...@@ -10754,6 +10754,43 @@ Please help our engineers fix this problem. Tell us what happened right before y ...@@ -10754,6 +10754,43 @@ Please help our engineers fix this problem. Tell us what happened right before y
other {Click to view these extensions}} other {Click to view these extensions}}
</message> </message>
</if> </if>
<if expr="is_macosx">
<!-- These strings are placeholders for strings that are filled in via
field trials, so they are *not* used as-is except in tests. -->
<message name="IDS_MAC_SYSTEM_INFOBAR_TEXT_ARM"
desc="Mac system-specific infobar text for Arm64-on-Arm64."
translateable="false">
This is an Arm64 Chrome on Arm64, so things might not work quite right
yet!
</message>
<message name="IDS_MAC_SYSTEM_INFOBAR_TEXT_ROSETTA"
desc="Mac system-specific infobar text for Intel-on-Arm64."
translateable="false">
This is an x86-64 Chrome on Arm64, so things might not work quite right
yet!
</message>
<message name="IDS_MAC_SYSTEM_INFOBAR_LINK_TEXT_ARM"
desc="Mac system-specific infobar link text for Arm64-on-Arm64."
translateable="false">
Learn more
</message>
<message name="IDS_MAC_SYSTEM_INFOBAR_LINK_URL_ARM"
desc="Mac system-specific infobar link for Arm64-on-Arm64."
translateable="false">
https://www.google.com
</message>
<message name="IDS_MAC_SYSTEM_INFOBAR_LINK_TEXT_ROSETTA"
desc="Mac system-specific infobar link text for Intel-on-Arm64."
translateable="false">
Learn more
</message>
<message name="IDS_MAC_SYSTEM_INFOBAR_LINK_URL_ROSETTA"
desc="Mac system-specific infobar link for Intel-on-Arm64."
translateable="false">
https://www.google.com
</message>
</if>
</messages> </messages>
</release> </release>
</grit> </grit>
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "chrome/browser/ui/startup/automation_infobar_delegate.h" #include "chrome/browser/ui/startup/automation_infobar_delegate.h"
#include "chrome/browser/ui/startup/bad_flags_prompt.h" #include "chrome/browser/ui/startup/bad_flags_prompt.h"
#include "chrome/browser/ui/startup/google_api_keys_infobar_delegate.h" #include "chrome/browser/ui/startup/google_api_keys_infobar_delegate.h"
#include "chrome/browser/ui/startup/mac_system_infobar_delegate.h"
#include "chrome/browser/ui/startup/obsolete_system_infobar_delegate.h" #include "chrome/browser/ui/startup/obsolete_system_infobar_delegate.h"
#include "chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h" #include "chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
...@@ -193,6 +194,7 @@ void InfoBarUiTest::ShowUi(const std::string& name) { ...@@ -193,6 +194,7 @@ void InfoBarUiTest::ShowUi(const std::string& name) {
{"plugin_observer", IBD::PLUGIN_OBSERVER_INFOBAR_DELEGATE}, {"plugin_observer", IBD::PLUGIN_OBSERVER_INFOBAR_DELEGATE},
{"file_access_disabled", IBD::FILE_ACCESS_DISABLED_INFOBAR_DELEGATE}, {"file_access_disabled", IBD::FILE_ACCESS_DISABLED_INFOBAR_DELEGATE},
{"keystone_promotion", IBD::KEYSTONE_PROMOTION_INFOBAR_DELEGATE_MAC}, {"keystone_promotion", IBD::KEYSTONE_PROMOTION_INFOBAR_DELEGATE_MAC},
{"mac_system", IBD::SYSTEM_INFOBAR_DELEGATE_MAC},
{"collected_cookies", IBD::COLLECTED_COOKIES_INFOBAR_DELEGATE}, {"collected_cookies", IBD::COLLECTED_COOKIES_INFOBAR_DELEGATE},
{"installation_error", IBD::INSTALLATION_ERROR_INFOBAR_DELEGATE}, {"installation_error", IBD::INSTALLATION_ERROR_INFOBAR_DELEGATE},
{"bad_flags", IBD::BAD_FLAGS_INFOBAR_DELEGATE}, {"bad_flags", IBD::BAD_FLAGS_INFOBAR_DELEGATE},
...@@ -299,6 +301,14 @@ void InfoBarUiTest::ShowUi(const std::string& name) { ...@@ -299,6 +301,14 @@ void InfoBarUiTest::ShowUi(const std::string& name) {
#endif #endif
break; break;
case IBD::SYSTEM_INFOBAR_DELEGATE_MAC:
#if defined(OS_MAC)
MacSystemInfoBarDelegate::Create(GetInfoBarService());
#else
ADD_FAILURE() << "This infobar is not supported on this OS.";
#endif
break;
case IBD::COLLECTED_COOKIES_INFOBAR_DELEGATE: case IBD::COLLECTED_COOKIES_INFOBAR_DELEGATE:
CollectedCookiesInfoBarDelegate::Create(GetInfoBarService()); CollectedCookiesInfoBarDelegate::Create(GetInfoBarService());
break; break;
...@@ -436,6 +446,9 @@ IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_file_access_disabled) { ...@@ -436,6 +446,9 @@ IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_file_access_disabled) {
IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_keystone_promotion) { IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_keystone_promotion) {
ShowAndVerifyUi(); ShowAndVerifyUi();
} }
IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_mac_system) {
ShowAndVerifyUi();
}
#endif #endif
IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_collected_cookies) { IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_collected_cookies) {
......
...@@ -2928,6 +2928,8 @@ static_library("ui") { ...@@ -2928,6 +2928,8 @@ static_library("ui") {
"content_settings/media_authorization_wrapper_test.h", "content_settings/media_authorization_wrapper_test.h",
"content_settings/media_authorization_wrapper_test.mm", "content_settings/media_authorization_wrapper_test.mm",
"find_bar/find_bar_platform_helper_mac.mm", "find_bar/find_bar_platform_helper_mac.mm",
"startup/mac_system_infobar_delegate.cc",
"startup/mac_system_infobar_delegate.h",
"views/apps/chrome_app_window_client_views_mac.mm", "views/apps/chrome_app_window_client_views_mac.mm",
"views/certificate_viewer_mac_views.mm", "views/certificate_viewer_mac_views.mm",
"views/dropdown_bar_host_mac.mm", "views/dropdown_bar_host_mac.mm",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/startup/mac_system_infobar_delegate.h"
#include "base/command_line.h"
#include "base/mac/mac_util.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/grit/generated_resources.h"
#include "components/infobars/core/infobar.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
using CPUType = base::mac::CPUType;
CPUType MaybeOverrideCPUTypeFromCommandLine(CPUType detected_type) {
// Use like: --force-mac-system-infobar={arm,rosetta,intel} to see different
// behavior by platform.
std::string forced_cpu =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
"force-mac-system-infobar");
if (forced_cpu == "arm")
return CPUType::kArm;
if (forced_cpu == "rosetta")
return CPUType::kTranslatedIntel;
if (forced_cpu == "intel")
return CPUType::kIntel;
return detected_type;
}
CPUType GetEffectiveCPUType() {
return MaybeOverrideCPUTypeFromCommandLine(base::mac::GetCPUType());
}
} // namespace
constexpr base::Feature MacSystemInfoBarDelegate::kMacSystemInfoBar;
// static
bool MacSystemInfoBarDelegate::ShouldShow() {
constexpr base::FeatureParam<bool> kEnableRosetta{&kMacSystemInfoBar,
"enable_rosetta", false};
constexpr base::FeatureParam<bool> kEnableArm{&kMacSystemInfoBar,
"enable_arm", false};
CPUType cpu = GetEffectiveCPUType();
return (cpu == CPUType::kTranslatedIntel && kEnableRosetta.Get()) ||
(cpu == CPUType::kArm && kEnableArm.Get());
}
// static
void MacSystemInfoBarDelegate::Create(InfoBarService* infobar_service) {
DCHECK(ShouldShow());
infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar(
std::unique_ptr<ConfirmInfoBarDelegate>(new MacSystemInfoBarDelegate())));
}
MacSystemInfoBarDelegate::MacSystemInfoBarDelegate() = default;
MacSystemInfoBarDelegate::~MacSystemInfoBarDelegate() = default;
bool MacSystemInfoBarDelegate::ShouldExpire(
const NavigationDetails& details) const {
// Don't dismiss on navigation - require an explicit dismissal. This infobar
// communicates an important thing (i.e. that the product is probably kind of
// broken).
return false;
}
infobars::InfoBarDelegate::InfoBarIdentifier
MacSystemInfoBarDelegate::GetIdentifier() const {
return SYSTEM_INFOBAR_DELEGATE_MAC;
}
base::string16 MacSystemInfoBarDelegate::GetLinkText() const {
return l10n_util::GetStringUTF16(
GetEffectiveCPUType() == CPUType::kArm
? IDS_MAC_SYSTEM_INFOBAR_LINK_TEXT_ARM
: IDS_MAC_SYSTEM_INFOBAR_LINK_TEXT_ROSETTA);
}
GURL MacSystemInfoBarDelegate::GetLinkURL() const {
return GURL(
l10n_util::GetStringUTF8(GetEffectiveCPUType() == CPUType::kArm
? IDS_MAC_SYSTEM_INFOBAR_LINK_URL_ARM
: IDS_MAC_SYSTEM_INFOBAR_LINK_URL_ROSETTA));
}
base::string16 MacSystemInfoBarDelegate::GetMessageText() const {
return l10n_util::GetStringUTF16(GetEffectiveCPUType() == CPUType::kArm
? IDS_MAC_SYSTEM_INFOBAR_TEXT_ARM
: IDS_MAC_SYSTEM_INFOBAR_TEXT_ROSETTA);
}
int MacSystemInfoBarDelegate::GetButtons() const {
return BUTTON_NONE;
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_STARTUP_MAC_SYSTEM_INFOBAR_DELEGATE_H_
#define CHROME_BROWSER_UI_STARTUP_MAC_SYSTEM_INFOBAR_DELEGATE_H_
#include "base/feature_list.h"
#include "base/strings/string16.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "url/gurl.h"
class InfoBarService;
// This infobar displays a message and link depending on the architecture of the
// Mac system. The message, link text, and link itself all come from grit, which
// allows them to be customized via field trials; placeholder values are present
// in the source grit files and marked as not translateable.
//
// In practice, this class will be used like this:
// 1. The MacSystemInfobar field trial is enabled
// 2. The "enable-arm" or "enable-rosetta" (or both) params for that trial
// are set to "1"
// 3. The IDS_MAC_SYSTEM_INFOBAR_* grit messages are overridden with
// appropriate text depending on the situation
//
// This allows the Mac-on-Arm launch process to "late bind" notification & help
// text in this infobar.
//
// The only logic in this infobar is for choosing between Arm string constants
// and Rosetta string constants. Once the field trial system becomes capable of
// qualifying study participants by architecture as well as OS version, this
// logic will go away as well, and this infobar will morph into a generic "show
// strings from a field trial whenever that field trial is active" type of
// infobar.
class MacSystemInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
static constexpr base::Feature kMacSystemInfoBar{
"MacSystemInfoBar",
base::FEATURE_DISABLED_BY_DEFAULT,
};
MacSystemInfoBarDelegate(const MacSystemInfoBarDelegate& other) = delete;
MacSystemInfoBarDelegate& operator=(const MacSystemInfoBarDelegate& other) =
delete;
// Returns whether this infobar should show or not, depending on the current
// CPU architecture and state of fieldtrials/switches.
static bool ShouldShow();
// Creates an instance of this infobar and adds it to the provided
// InfoBarService. It is an error to call this method if !ShouldShow().
static void Create(InfoBarService* infobar_service);
private:
MacSystemInfoBarDelegate();
~MacSystemInfoBarDelegate() override;
// ConfirmInfoBarDelegate:
bool ShouldExpire(const NavigationDetails& details) const override;
infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
base::string16 GetLinkText() const override;
GURL GetLinkURL() const override;
base::string16 GetMessageText() const override;
int GetButtons() const override;
};
#endif // CHROME_BROWSER_UI_STARTUP_MAC_SYSTEM_INFOBAR_DELEGATE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/startup/mac_system_infobar_delegate.h"
#include "base/mac/mac_util.h"
#include "base/test/scoped_feature_list.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
using CPUType = base::mac::CPUType;
void ForceArchForTest(CPUType type) {
const char kSwitch[] = "force-mac-system-infobar";
auto* command_line = base::CommandLine::ForCurrentProcess();
if (type == CPUType::kArm)
command_line->AppendSwitchASCII(kSwitch, "arm");
else if (type == CPUType::kTranslatedIntel)
command_line->AppendSwitchASCII(kSwitch, "rosetta");
else if (type == CPUType::kIntel)
command_line->AppendSwitchASCII(kSwitch, "intel");
}
class MacSystemInfoBarDelegateArmTest : public testing::Test {
public:
void SetUp() override {
base::FieldTrialParams params;
params["enable_arm"] = "true";
features_.InitAndEnableFeatureWithParameters(
MacSystemInfoBarDelegate::kMacSystemInfoBar, params);
}
private:
base::test::ScopedFeatureList features_;
};
class MacSystemInfoBarDelegateRosettaTest : public testing::Test {
public:
void SetUp() override {
base::FieldTrialParams params;
params["enable_rosetta"] = "true";
features_.InitAndEnableFeatureWithParameters(
MacSystemInfoBarDelegate::kMacSystemInfoBar, params);
}
private:
base::test::ScopedFeatureList features_;
};
class MacSystemInfoBarDelegateTest : public testing::Test {
public:
void SetUp() override {
features_.InitAndEnableFeature(MacSystemInfoBarDelegate::kMacSystemInfoBar);
}
private:
base::test::ScopedFeatureList features_;
};
// Test that the enable/disable logic works properly on Arm.
TEST_F(MacSystemInfoBarDelegateArmTest, EnabledForArm) {
ForceArchForTest(CPUType::kArm);
ASSERT_TRUE(MacSystemInfoBarDelegate::ShouldShow());
ForceArchForTest(CPUType::kTranslatedIntel);
EXPECT_FALSE(MacSystemInfoBarDelegate::ShouldShow());
ForceArchForTest(CPUType::kIntel);
EXPECT_FALSE(MacSystemInfoBarDelegate::ShouldShow());
}
// Test that the enable/disable logic works properly on Rosetta.
TEST_F(MacSystemInfoBarDelegateRosettaTest, EnabledForRosetta) {
ForceArchForTest(CPUType::kTranslatedIntel);
ASSERT_TRUE(MacSystemInfoBarDelegate::ShouldShow());
ForceArchForTest(CPUType::kArm);
EXPECT_FALSE(MacSystemInfoBarDelegate::ShouldShow());
ForceArchForTest(CPUType::kIntel);
EXPECT_FALSE(MacSystemInfoBarDelegate::ShouldShow());
}
// Test that nothing is enabled when the feature is disabled.
TEST_F(MacSystemInfoBarDelegateTest, NotEnabledAnywhere) {
ForceArchForTest(CPUType::kTranslatedIntel);
EXPECT_FALSE(MacSystemInfoBarDelegate::ShouldShow());
ForceArchForTest(CPUType::kArm);
EXPECT_FALSE(MacSystemInfoBarDelegate::ShouldShow());
ForceArchForTest(CPUType::kIntel);
EXPECT_FALSE(MacSystemInfoBarDelegate::ShouldShow());
}
} // namespace
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
#import "chrome/browser/mac/dock.h" #import "chrome/browser/mac/dock.h"
#include "chrome/browser/mac/install_from_dmg.h" #include "chrome/browser/mac/install_from_dmg.h"
#include "chrome/browser/ui/cocoa/keystone_infobar_delegate.h" #include "chrome/browser/ui/cocoa/keystone_infobar_delegate.h"
#include "chrome/browser/ui/startup/mac_system_infobar_delegate.h"
#endif #endif
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -913,6 +914,11 @@ void StartupBrowserCreatorImpl::AddInfoBarsIfNecessary( ...@@ -913,6 +914,11 @@ void StartupBrowserCreatorImpl::AddInfoBarsIfNecessary(
ObsoleteSystemInfoBarDelegate::Create(infobar_service); ObsoleteSystemInfoBarDelegate::Create(infobar_service);
} }
#if defined(OS_MAC)
if (MacSystemInfoBarDelegate::ShouldShow())
MacSystemInfoBarDelegate::Create(infobar_service);
#endif
#if !defined(OS_CHROMEOS) #if !defined(OS_CHROMEOS)
if (!command_line_.HasSwitch(switches::kNoDefaultBrowserCheck)) { if (!command_line_.HasSwitch(switches::kNoDefaultBrowserCheck)) {
// The default browser prompt should only be shown after the first run. // The default browser prompt should only be shown after the first run.
......
...@@ -5129,6 +5129,10 @@ test("unit_tests") { ...@@ -5129,6 +5129,10 @@ test("unit_tests") {
"../browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc", "../browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc",
] ]
} }
if (is_mac) {
sources +=
[ "../browser/ui/startup/mac_system_infobar_delegate_unittest.cc" ]
}
if (is_chromeos) { if (is_chromeos) {
sources += [ sources += [
"../browser/chromeos/extensions/extensions_permissions_tracker_unittest.cc", "../browser/chromeos/extensions/extensions_permissions_tracker_unittest.cc",
......
...@@ -168,6 +168,7 @@ class InfoBarDelegate { ...@@ -168,6 +168,7 @@ class InfoBarDelegate {
MIXED_CONTENT_DOWNLOAD_INFOBAR_DELEGATE_ANDROID = 98, MIXED_CONTENT_DOWNLOAD_INFOBAR_DELEGATE_ANDROID = 98,
CONDITIONAL_TAB_STRIP_INFOBAR_ANDROID = 99, CONDITIONAL_TAB_STRIP_INFOBAR_ANDROID = 99,
LITE_MODE_HTTPS_IMAGE_COMPRESSION_INFOBAR_ANDROID = 100, LITE_MODE_HTTPS_IMAGE_COMPRESSION_INFOBAR_ANDROID = 100,
SYSTEM_INFOBAR_DELEGATE_MAC = 101,
}; };
// Describes navigation events, used to decide whether infobars should be // Describes navigation events, used to decide whether infobars should be
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment