blob: 6e191d742ef79a5e890d1bf0c8ea9016705944f1 [file] [log] [blame]
// 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/accessibility/caption_controller.h"
#include "base/files/file_path.h"
#include "base/ranges/ranges.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/accessibility/caption_controller_factory.h"
#include "chrome/browser/accessibility/caption_host_impl.h"
#include "chrome/browser/browser_features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_keep_alive_types.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/profiles/scoped_profile_keep_alive.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/caption_bubble_controller.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/soda/pref_names.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "content/public/test/browser_test.h"
#include "media/base/media_switches.h"
namespace captions {
// Blocks until a new profile is created.
void UnblockOnProfileCreation(base::RunLoop* run_loop,
Profile* profile,
Profile::CreateStatus status) {
if (status == Profile::CREATE_STATUS_INITIALIZED)
run_loop->Quit();
}
Profile* CreateProfile() {
ProfileManager* profile_manager = g_browser_process->profile_manager();
base::FilePath profile_path =
profile_manager->GenerateNextProfileDirectoryPath();
base::RunLoop run_loop;
profile_manager->CreateProfileAsync(
profile_path, base::BindRepeating(&UnblockOnProfileCreation, &run_loop));
run_loop.Run();
return profile_manager->GetProfileByPath(profile_path);
}
class CaptionControllerTest : public InProcessBrowserTest {
public:
CaptionControllerTest() = default;
~CaptionControllerTest() override = default;
CaptionControllerTest(const CaptionControllerTest&) = delete;
CaptionControllerTest& operator=(const CaptionControllerTest&) = delete;
// InProcessBrowserTest overrides:
void SetUp() override {
scoped_feature_list_.InitWithFeatures(
{media::kLiveCaption, media::kUseSodaForLiveCaption}, {});
InProcessBrowserTest::SetUp();
}
void SetLiveCaptionEnabled(bool enabled) {
browser()->profile()->GetPrefs()->SetBoolean(prefs::kLiveCaptionEnabled,
enabled);
if (enabled)
speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting();
}
void SetLiveCaptionEnabledForProfile(bool enabled, Profile* profile) {
profile->GetPrefs()->SetBoolean(prefs::kLiveCaptionEnabled, enabled);
if (enabled)
speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting();
}
CaptionController* GetController() {
return GetControllerForBrowser(browser());
}
CaptionController* GetControllerForBrowser(Browser* browser) {
return GetControllerForProfile(browser->profile());
}
CaptionController* GetControllerForProfile(Profile* profile) {
return CaptionControllerFactory::GetForProfile(profile);
}
CaptionBubbleController* GetBubbleController() {
return GetBubbleControllerForBrowser(browser());
}
CaptionBubbleController* GetBubbleControllerForBrowser(Browser* browser) {
return GetControllerForBrowser(browser)
->GetCaptionBubbleControllerForBrowser(browser);
}
CaptionHostImpl* GetCaptionHostImplForBrowser(Browser* browser) {
if (!caption_host_impls_.count(browser)) {
caption_host_impls_.emplace(browser, std::make_unique<CaptionHostImpl>(
browser->tab_strip_model()
->GetActiveWebContents()
->GetMainFrame()));
}
return caption_host_impls_[browser].get();
}
bool DispatchTranscription(std::string text) {
return DispatchTranscriptionToBrowser(text, browser());
}
bool DispatchTranscriptionToBrowser(std::string text, Browser* browser) {
return DispatchTranscriptionToBrowserForProfile(text, browser,
browser->profile());
}
bool DispatchTranscriptionToBrowserForProfile(std::string text,
Browser* browser,
Profile* profile) {
return GetControllerForProfile(profile)->DispatchTranscription(
GetCaptionHostImplForBrowser(browser),
chrome::mojom::TranscriptionResult::New(text, false /* is_final */));
}
void OnError() { OnErrorOnBrowser(browser()); }
void OnErrorOnBrowser(Browser* browser) {
OnErrorOnBrowserForProfile(browser, browser->profile());
}
void OnErrorOnBrowserForProfile(Browser* browser, Profile* profile) {
GetControllerForProfile(profile)->OnError(
GetCaptionHostImplForBrowser(browser));
}
void OnAudioStreamEnd() { OnAudioStreamEndOnBrowser(browser()); }
void OnAudioStreamEndOnBrowser(Browser* browser) {
OnAudioStreamEndOnBrowserForProfile(browser, browser->profile());
}
void OnAudioStreamEndOnBrowserForProfile(Browser* browser, Profile* profile) {
GetControllerForProfile(profile)->OnAudioStreamEnd(
GetCaptionHostImplForBrowser(browser));
}
int NumBubbleControllers() {
return NumBubbleControllersForProfile(browser()->profile());
}
int NumBubbleControllersForProfile(Profile* profile) {
return GetControllerForProfile(profile)->caption_bubble_controllers_.size();
}
void ExpectIsWidgetVisible(bool visible) {
ExpectIsWidgetVisibleOnBrowser(visible, browser());
}
void ExpectIsWidgetVisibleOnBrowser(bool visible, Browser* browser) {
#if defined(TOOLKIT_VIEWS)
EXPECT_EQ(
visible,
GetBubbleControllerForBrowser(browser)->IsWidgetVisibleForTesting());
#endif
}
void ExpectBubbleLabelTextEquals(std::string text) {
ExpectBubbleLabelTextOnBrowserEquals(text, browser());
}
void ExpectBubbleLabelTextOnBrowserEquals(std::string text,
Browser* browser) {
#if defined(TOOLKIT_VIEWS)
EXPECT_EQ(
text,
GetBubbleControllerForBrowser(browser)->GetBubbleLabelTextForTesting());
#endif
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
std::unordered_map<Browser*, std::unique_ptr<CaptionHostImpl>>
caption_host_impls_;
};
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, ProfilePrefsAreRegistered) {
EXPECT_FALSE(
browser()->profile()->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled));
EXPECT_EQ(base::FilePath(), g_browser_process->local_state()->GetFilePath(
prefs::kSodaBinaryPath));
EXPECT_EQ(base::FilePath(), g_browser_process->local_state()->GetFilePath(
prefs::kSodaEnUsConfigPath));
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest,
ProfilePrefsAreRegistered_Incognito) {
// Set live caption enabled on the regular profile.
SetLiveCaptionEnabled(true);
EXPECT_TRUE(
browser()->profile()->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled));
EXPECT_EQ(base::FilePath(), g_browser_process->local_state()->GetFilePath(
prefs::kSodaBinaryPath));
EXPECT_EQ(base::FilePath(), g_browser_process->local_state()->GetFilePath(
prefs::kSodaEnUsConfigPath));
// Ensure that live caption is also enabled in the incognito profile.
Profile* incognito_profile = browser()->profile()->GetPrimaryOTRProfile();
EXPECT_TRUE(
incognito_profile->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled));
EXPECT_EQ(base::FilePath(), g_browser_process->local_state()->GetFilePath(
prefs::kSodaBinaryPath));
EXPECT_EQ(base::FilePath(), g_browser_process->local_state()->GetFilePath(
prefs::kSodaEnUsConfigPath));
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, LiveCaptionEnabledChanged) {
EXPECT_EQ(nullptr, GetBubbleController());
EXPECT_EQ(0, NumBubbleControllers());
SetLiveCaptionEnabled(true);
EXPECT_NE(nullptr, GetBubbleController());
EXPECT_EQ(1, NumBubbleControllers());
SetLiveCaptionEnabled(false);
EXPECT_EQ(nullptr, GetBubbleController());
EXPECT_EQ(0, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest,
LiveCaptionEnabledChanged_BubbleVisible) {
SetLiveCaptionEnabled(true);
// Make the bubble visible by dispatching a transcription.
DispatchTranscription(
"In Switzerland it is illegal to own just one guinea pig.");
ExpectIsWidgetVisible(true);
SetLiveCaptionEnabled(false);
EXPECT_EQ(nullptr, GetBubbleController());
EXPECT_EQ(0, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnSodaInstalled) {
EXPECT_EQ(0, NumBubbleControllers());
browser()->profile()->GetPrefs()->SetBoolean(prefs::kLiveCaptionEnabled,
true);
EXPECT_EQ(0, NumBubbleControllers());
// The UI is only created after SODA is installed.
speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting();
EXPECT_EQ(1, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnBrowserAdded) {
EXPECT_EQ(0, NumBubbleControllers());
// Add a new browser and then enable live caption. Test that a caption bubble
// controller is created.
CreateBrowser(browser()->profile());
SetLiveCaptionEnabled(true);
EXPECT_EQ(2, NumBubbleControllers());
// Add a new browser and test that a caption bubble controller is created.
CreateBrowser(browser()->profile());
EXPECT_EQ(3, NumBubbleControllers());
// Disable live caption. Add a new browser and test that a caption bubble
// controller is not created.
SetLiveCaptionEnabled(false);
CreateBrowser(browser()->profile());
EXPECT_EQ(0, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnBrowserAdded_Incognito) {
EXPECT_EQ(0, NumBubbleControllers());
// Add a new incognito browser and then enable live caption. Test that a
// caption bubble controller is created in each browser (incognito and
// regular).
CreateIncognitoBrowser();
SetLiveCaptionEnabled(true);
EXPECT_EQ(2, NumBubbleControllers());
// Add a new incognito browser and test that a caption bubble controller is
// created.
CreateIncognitoBrowser();
EXPECT_EQ(3, NumBubbleControllers());
// Disable live caption. Add a new incognito browser and test that a caption
// bubble controller is not created.
SetLiveCaptionEnabled(false);
CreateIncognitoBrowser();
EXPECT_EQ(0, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnBrowserRemoved) {
Profile* profile = browser()->profile();
CaptionController* controller = GetController();
Browser* browser1 = browser();
// Add 3 browsers.
Browser* browser2 = CreateBrowser(profile);
Browser* browser3 = CreateBrowser(profile);
Browser* browser4 = CreateBrowser(profile);
SetLiveCaptionEnabled(true);
EXPECT_EQ(4, NumBubbleControllers());
// Close browser4 and test that the caption bubble controller was destroyed.
browser4->window()->Close();
ui_test_utils::WaitForBrowserToClose();
EXPECT_EQ(nullptr,
controller->GetCaptionBubbleControllerForBrowser(browser4));
EXPECT_EQ(3, NumBubbleControllers());
// Make the bubble on browser3 visible by dispatching a transcription.
DispatchTranscriptionToBrowser(
"If you lift a kangaroo's tail off the ground it can't hop.", browser3);
ExpectIsWidgetVisibleOnBrowser(true, browser3);
browser3->window()->Close();
ui_test_utils::WaitForBrowserToClose();
EXPECT_EQ(nullptr,
controller->GetCaptionBubbleControllerForBrowser(browser3));
EXPECT_EQ(2, NumBubbleControllers());
// Make the bubble on browser2 visible by dispatching a transcription.
DispatchTranscriptionToBrowser(
"A lion's roar can be heard from 5 miles away.", browser2);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
// Close all browsers and verify that the caption bubbles are destroyed on
// the two remaining browsers.
chrome::CloseAllBrowsers();
ui_test_utils::WaitForBrowserToClose();
ui_test_utils::WaitForBrowserToClose();
if (base::FeatureList::IsEnabled(features::kDestroyProfileOnBrowserClose)) {
// With DestroyProfileOnBrowserClose, the Profile* is deleted entirely.
//
// TODO(crbug.com/88586): Remove the other branch once
// DestroyProfileOnBrowserClose becomes the default.
base::RunLoop().RunUntilIdle();
std::vector<Profile*> loaded_profiles =
g_browser_process->profile_manager()->GetLoadedProfiles();
auto it = base::ranges::find(loaded_profiles, profile);
EXPECT_EQ(loaded_profiles.end(), it);
} else {
EXPECT_EQ(nullptr,
controller->GetCaptionBubbleControllerForBrowser(browser2));
EXPECT_EQ(nullptr,
controller->GetCaptionBubbleControllerForBrowser(browser1));
}
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnBrowserRemoved_Incognito) {
CaptionController* controller = GetController();
Browser* incognito_browser1 = CreateIncognitoBrowser();
Browser* incognito_browser2 = CreateIncognitoBrowser();
SetLiveCaptionEnabled(true);
// There is 1 regular browser and 2 incognito browsers.
EXPECT_EQ(3, NumBubbleControllers());
// Close incognito_browser2 and test that the caption bubble controller was
// destroyed.
incognito_browser2->window()->Close();
ui_test_utils::WaitForBrowserToClose();
EXPECT_EQ(nullptr, controller->GetCaptionBubbleControllerForBrowser(
incognito_browser2));
EXPECT_EQ(2, NumBubbleControllers());
// Make the bubble on incognito_browser1 visible by dispatching a
// transcription.
DispatchTranscriptionToBrowser(
"If you lift a kangaroo's tail off the ground it can't hop.",
incognito_browser1);
ExpectIsWidgetVisibleOnBrowser(true, incognito_browser1);
incognito_browser1->window()->Close();
ui_test_utils::WaitForBrowserToClose();
EXPECT_EQ(nullptr, controller->GetCaptionBubbleControllerForBrowser(
incognito_browser1));
EXPECT_EQ(1, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, DispatchTranscription) {
bool success = DispatchTranscription("A baby spider is called a spiderling.");
EXPECT_FALSE(success);
EXPECT_EQ(0, NumBubbleControllers());
SetLiveCaptionEnabled(true);
success = DispatchTranscription(
"A baby octopus is about the size of a flea when it is born.");
EXPECT_TRUE(success);
ExpectIsWidgetVisible(true);
ExpectBubbleLabelTextEquals(
"A baby octopus is about the size of a flea when it is born.");
SetLiveCaptionEnabled(false);
success = DispatchTranscription(
"Approximately 10-20% of power outages in the US are caused by "
"squirrels.");
EXPECT_FALSE(success);
EXPECT_EQ(0, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest,
DispatchTranscription_MultipleBrowsers) {
Browser* browser1 = browser();
Browser* browser2 = CreateBrowser(browser()->profile());
Browser* incognito_browser = CreateIncognitoBrowser();
SetLiveCaptionEnabled(true);
// Dispatch transcription routes the transcription to the right browser.
bool success = DispatchTranscriptionToBrowser(
"Honeybees can recognize human faces.", browser1);
EXPECT_TRUE(success);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser2);
ExpectIsWidgetVisibleOnBrowser(false, incognito_browser);
ExpectBubbleLabelTextOnBrowserEquals("Honeybees can recognize human faces.",
browser1);
ExpectBubbleLabelTextOnBrowserEquals("", browser2);
ExpectBubbleLabelTextOnBrowserEquals("", incognito_browser);
success = DispatchTranscriptionToBrowser(
"A blue whale's heart is the size of a small car.", browser2);
EXPECT_TRUE(success);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
ExpectIsWidgetVisibleOnBrowser(false, incognito_browser);
ExpectBubbleLabelTextOnBrowserEquals(
"A blue whale's heart is the size of a small car.", browser2);
ExpectBubbleLabelTextOnBrowserEquals("Honeybees can recognize human faces.",
browser1);
ExpectBubbleLabelTextOnBrowserEquals("", incognito_browser);
success = DispatchTranscriptionToBrowser(
"Squirrels forget where they hide about half of their nuts.",
incognito_browser);
EXPECT_TRUE(success);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
ExpectIsWidgetVisibleOnBrowser(true, incognito_browser);
ExpectBubbleLabelTextOnBrowserEquals(
"A blue whale's heart is the size of a small car.", browser2);
ExpectBubbleLabelTextOnBrowserEquals("Honeybees can recognize human faces.",
browser1);
ExpectBubbleLabelTextOnBrowserEquals(
"Squirrels forget where they hide about half of their nuts.",
incognito_browser);
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnError) {
OnError();
EXPECT_EQ(0, NumBubbleControllers());
SetLiveCaptionEnabled(true);
OnError();
ExpectIsWidgetVisible(true);
SetLiveCaptionEnabled(false);
OnError();
EXPECT_EQ(0, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnError_MultipleBrowsers) {
Browser* browser1 = browser();
Browser* browser2 = CreateBrowser(browser()->profile());
Browser* incognito_browser = CreateIncognitoBrowser();
SetLiveCaptionEnabled(true);
// OnError routes to the right browser.
OnErrorOnBrowser(browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser2);
ExpectIsWidgetVisibleOnBrowser(false, incognito_browser);
OnErrorOnBrowser(browser2);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
ExpectIsWidgetVisibleOnBrowser(false, incognito_browser);
OnErrorOnBrowser(incognito_browser);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
ExpectIsWidgetVisibleOnBrowser(true, incognito_browser);
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnAudioStreamEnd) {
OnAudioStreamEnd();
EXPECT_EQ(0, NumBubbleControllers());
SetLiveCaptionEnabled(true);
DispatchTranscription("Some cicadas appear only once every 17 years.");
ExpectIsWidgetVisible(true);
OnAudioStreamEnd();
ExpectIsWidgetVisible(false);
SetLiveCaptionEnabled(false);
OnAudioStreamEnd();
EXPECT_EQ(0, NumBubbleControllers());
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest,
OnAudioStreamEnd_MultipleBrowsers) {
Browser* browser1 = browser();
Browser* browser2 = CreateBrowser(browser()->profile());
Browser* incognito_browser = CreateIncognitoBrowser();
SetLiveCaptionEnabled(true);
DispatchTranscriptionToBrowser("Ladybugs are beetles, not bugs.", browser1);
DispatchTranscriptionToBrowser("Ladybugs eat 5000 bugs in their lifetimes.",
browser2);
DispatchTranscriptionToBrowser("Ladybugs have up to 20 spots.",
incognito_browser);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
ExpectIsWidgetVisibleOnBrowser(true, incognito_browser);
// OnAudioStreamEnd routes to the right browser.
OnAudioStreamEndOnBrowser(browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
ExpectIsWidgetVisibleOnBrowser(true, incognito_browser);
OnAudioStreamEndOnBrowser(browser2);
ExpectIsWidgetVisibleOnBrowser(false, browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser2);
ExpectIsWidgetVisibleOnBrowser(true, incognito_browser);
OnAudioStreamEndOnBrowser(incognito_browser);
ExpectIsWidgetVisibleOnBrowser(false, browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser2);
ExpectIsWidgetVisibleOnBrowser(false, incognito_browser);
}
#if !BUILDFLAG(IS_CHROMEOS_ASH) // No multi-profile on ChromeOS.
IN_PROC_BROWSER_TEST_F(CaptionControllerTest,
LiveCaptionEnabledChanged_MultipleProfiles) {
Profile* profile1 = browser()->profile();
Profile* profile2 = CreateProfile();
CreateBrowser(profile2);
// The profiles start with no caption bubble controllers.
EXPECT_EQ(0, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(0, NumBubbleControllersForProfile(profile2));
// Enable live caption on profile1.
SetLiveCaptionEnabled(true);
EXPECT_EQ(1, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(0, NumBubbleControllersForProfile(profile2));
// Enable live caption on profile2.
SetLiveCaptionEnabledForProfile(true, profile2);
EXPECT_EQ(1, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(1, NumBubbleControllersForProfile(profile2));
// Disable live caption on profile1.
SetLiveCaptionEnabled(false);
EXPECT_EQ(0, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(1, NumBubbleControllersForProfile(profile2));
// Disable live caption on profile2.
SetLiveCaptionEnabledForProfile(false, profile2);
EXPECT_EQ(0, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(0, NumBubbleControllersForProfile(profile2));
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnBrowserAdded_MultipleProfiles) {
Profile* profile1 = browser()->profile();
Profile* profile2 = CreateProfile();
// Enable live caption on both profiles.
SetLiveCaptionEnabled(true);
SetLiveCaptionEnabledForProfile(true, profile2);
// Add a new browser to profile1. Test that there are caption bubble
// controllers on all of the existing browsers.
CreateBrowser(profile1);
EXPECT_EQ(2, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(0, NumBubbleControllersForProfile(profile2));
// Add a new browser to profile 2. Test that a caption bubble controller is
// created in profile2 and not in profile1.
Browser* profile2_browser2 = CreateBrowser(profile2);
EXPECT_NE(
nullptr,
GetControllerForProfile(profile2)->GetCaptionBubbleControllerForBrowser(
profile2_browser2));
EXPECT_EQ(
nullptr,
GetControllerForProfile(profile1)->GetCaptionBubbleControllerForBrowser(
profile2_browser2));
EXPECT_EQ(2, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(1, NumBubbleControllersForProfile(profile2));
// Disable live caption on profile1. Add a new browser to both profiles, and
// test that a caption bubble controller is only created on profile2.
SetLiveCaptionEnabled(false);
EXPECT_EQ(0, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(1, NumBubbleControllersForProfile(profile2));
CreateBrowser(profile1);
CreateBrowser(profile2);
EXPECT_EQ(0, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(2, NumBubbleControllersForProfile(profile2));
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest,
OnBrowserRemoved_MultipleProfiles) {
Profile* profile1 = browser()->profile();
Profile* profile2 = CreateProfile();
Browser* browser1 = browser();
Browser* browser2 = CreateBrowser(profile2);
CaptionController* controller1 = GetControllerForProfile(profile1);
CaptionController* controller2 = GetControllerForProfile(profile2);
// TODO(crbug.com/88586): Remove this test when the
// DestroyProfileOnBrowserClose flag is removed.
ScopedProfileKeepAlive profile1_keep_alive(
profile1, ProfileKeepAliveOrigin::kBrowserWindow);
ScopedProfileKeepAlive profile2_keep_alive(
profile2, ProfileKeepAliveOrigin::kBrowserWindow);
// Enable live caption on both profiles.
SetLiveCaptionEnabled(true);
SetLiveCaptionEnabledForProfile(true, profile2);
EXPECT_EQ(1, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(1, NumBubbleControllersForProfile(profile2));
// Close browser2 and test that the caption bubble controller was destroyed.
browser2->window()->Close();
ui_test_utils::WaitForBrowserToClose();
EXPECT_EQ(nullptr,
controller2->GetCaptionBubbleControllerForBrowser(browser2));
EXPECT_EQ(1, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(0, NumBubbleControllersForProfile(profile2));
// Make the bubble on incognito_browser1 visible by dispatching a
// transcription.
DispatchTranscriptionToBrowser(
"If you lift a kangaroo's tail off the ground it can't hop.", browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
browser1->window()->Close();
ui_test_utils::WaitForBrowserToClose();
EXPECT_EQ(nullptr,
controller1->GetCaptionBubbleControllerForBrowser(browser1));
EXPECT_EQ(0, NumBubbleControllersForProfile(profile1));
EXPECT_EQ(0, NumBubbleControllersForProfile(profile2));
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest,
DispatchTranscription_MultipleProfiles) {
Profile* profile1 = browser()->profile();
Profile* profile2 = CreateProfile();
Browser* browser1 = browser();
Browser* browser2 = CreateBrowser(profile2);
// Enable live caption on both profiles.
SetLiveCaptionEnabled(true);
SetLiveCaptionEnabledForProfile(true, profile2);
// Dispatch transcription routes the transcription to the right browser on the
// right profile.
bool success = DispatchTranscriptionToBrowserForProfile(
"Only female mosquitos bite.", browser1, profile1);
EXPECT_TRUE(success);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser2);
ExpectBubbleLabelTextOnBrowserEquals("Only female mosquitos bite.", browser1);
ExpectBubbleLabelTextOnBrowserEquals("", browser2);
success = DispatchTranscriptionToBrowserForProfile(
"Mosquitos were around at the time of the dinosaurs.", browser2,
profile2);
EXPECT_TRUE(success);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
ExpectBubbleLabelTextOnBrowserEquals("Only female mosquitos bite.", browser1);
ExpectBubbleLabelTextOnBrowserEquals(
"Mosquitos were around at the time of the dinosaurs.", browser2);
// Dispatch transcription returns false for browsers on different profiles.
success = DispatchTranscriptionToBrowserForProfile(
"There are over 3000 species of mosquitos.", browser1, profile2);
EXPECT_FALSE(success);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
ExpectBubbleLabelTextOnBrowserEquals("Only female mosquitos bite.", browser1);
ExpectBubbleLabelTextOnBrowserEquals(
"Mosquitos were around at the time of the dinosaurs.", browser2);
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest, OnError_MultipleProfiles) {
Profile* profile1 = browser()->profile();
Profile* profile2 = CreateProfile();
Browser* browser1 = browser();
Browser* browser2 = CreateBrowser(profile2);
// Enable live caption on both profiles.
SetLiveCaptionEnabled(true);
SetLiveCaptionEnabledForProfile(true, profile2);
// OnError routes to the right browser on the right profile.
OnErrorOnBrowserForProfile(browser1, profile1);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser2);
OnErrorOnBrowserForProfile(browser2, profile2);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
// OnError does nothing when sent to browsers on different profiles.
OnErrorOnBrowserForProfile(browser1, profile2);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
}
IN_PROC_BROWSER_TEST_F(CaptionControllerTest,
OnAudioStreamEnd_MultipleProfiles) {
Profile* profile1 = browser()->profile();
Profile* profile2 = CreateProfile();
Browser* browser1 = browser();
Browser* browser2 = CreateBrowser(profile2);
// Enable live caption on both profiles.
SetLiveCaptionEnabled(true);
SetLiveCaptionEnabledForProfile(true, profile2);
DispatchTranscriptionToBrowserForProfile(
"Capybaras are the largest rodents in the world.", browser1, profile1);
DispatchTranscriptionToBrowserForProfile(
"Capybaras' teeth grow continuously.", browser2, profile2);
ExpectIsWidgetVisibleOnBrowser(true, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
// OnAudioStreamEnd routes to the right browser on the right profile.
OnAudioStreamEndOnBrowserForProfile(browser1, profile1);
ExpectIsWidgetVisibleOnBrowser(false, browser1);
ExpectIsWidgetVisibleOnBrowser(true, browser2);
OnAudioStreamEndOnBrowserForProfile(browser2, profile2);
ExpectIsWidgetVisibleOnBrowser(false, browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser2);
// OnAudioStreamEnd does nothing when sent to browsers on different profiles.
OnAudioStreamEndOnBrowserForProfile(browser1, profile2);
ExpectIsWidgetVisibleOnBrowser(false, browser1);
ExpectIsWidgetVisibleOnBrowser(false, browser2);
}
#endif // !BUILDFLAG(IS_CHROMEOS_ASH)
} // namespace captions