VC UI: Add nudge for both camera and microphone in use while disabled
Due to some constraint in VideoConferenceManagerAsh, when both microphone and camera is being accessed when disabled, `HandleDeviceUsedWhileDisabled` will be called twice for each device. Thus, we need to wait for both 2 calls and display one nudge for both. Fixed: b:273570886 Change-Id: Ia271a90ba0dc8e36c7501019e922b0b3667cc56d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4705990 Commit-Queue: Andre Le <leandre@chromium.org> Reviewed-by: Alex Newcomer <newcomer@chromium.org> Reviewed-by: James Cook <jamescook@chromium.org> Cr-Commit-Position: refs/heads/main@{#1174302}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
aec792867c
commit
fcacfc7827
ash
ash_strings.grd
ash_strings_grd
IDS_ASH_VIDEO_CONFERENCE_CAMERA_MICROPHONE_NAME.png.sha1IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED.png.sha1
constants
system
chrome/browser/ash/video_conference
tools/metrics/histograms
@ -1629,7 +1629,7 @@ Style notes:
|
||||
<message name="IDS_ASH_VIDEO_CONFERENCE_TOAST_SPEAK_ON_MUTE_DETECTED" desc="A toast message that we show when user tries to speak while muted on system-level.">
|
||||
Are you talking? Your mic is off. Select the mic to turn it on.
|
||||
</message>
|
||||
<message name="IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_SOFTWARE_DISABLED" desc="A toast message that we show when an app tries to access camera or microphone while it is disabled by software.">
|
||||
<message name="IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED" desc="A toast message that we show when an app tries to access camera or microphone while it is disabled by software.">
|
||||
<ph name="APP_NAME">$1<ex>Meet</ex></ph> wants to use your <ph name="DEVICE_NAME">$2<ex>camera</ex></ph>
|
||||
</message>
|
||||
<message name="IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_HARDWARE_DISABLED" desc="A toast message that we show when an app tries to access camera or microphone while it is disabled by hardware.">
|
||||
@ -1662,6 +1662,9 @@ Style notes:
|
||||
<message name="IDS_ASH_VIDEO_CONFERENCE_MICROPHONE_NAME" desc="Text display for the microphone.">
|
||||
microphone
|
||||
</message>
|
||||
<message name="IDS_ASH_VIDEO_CONFERENCE_CAMERA_MICROPHONE_NAME" desc="Text display for both the camera and microphone.">
|
||||
camera and microphone
|
||||
</message>
|
||||
<message name="VIDEO_CONFERENCE_RETURN_TO_APP_PERIPHERALS_ACCESSIBLE_NAME" desc="Tooltip shown for the return to app button regarding peripherals in the video conference panel.">
|
||||
<ph name="CAPTURE_MEDIUM">$1<ex>Camera</ex></ph> in use.
|
||||
</message>
|
||||
|
@ -0,0 +1 @@
|
||||
e4271f7390f667a1a8c209f5e488999f4d8fc56d
|
@ -216,7 +216,8 @@ enum class NudgeCatalogName {
|
||||
kVideoConferenceTraySpeakOnMuteOptIn = 16,
|
||||
kVideoConferenceTraySpeakOnMuteOptInConfirmation = 17,
|
||||
kScalableIphBubble = 18,
|
||||
kMaxValue = kScalableIphBubble
|
||||
kVideoConferenceTrayCameraMicrophoneUseWhileDisabled = 19,
|
||||
kMaxValue = kVideoConferenceTrayCameraMicrophoneUseWhileDisabled
|
||||
};
|
||||
|
||||
// A living catalog that registers toasts.
|
||||
|
@ -66,6 +66,8 @@ constexpr char kVideoConferenceTrayCameraUseWhileHWDisabledNudgeId[] =
|
||||
"video_conference_tray_nudge_ids.camera_use_while_hw_disabled";
|
||||
constexpr char kVideoConferenceTrayCameraUseWhileSWDisabledNudgeId[] =
|
||||
"video_conference_tray_nudge_ids.camera_use_while_sw_disabled";
|
||||
constexpr char kVideoConferenceTrayBothUseWhileDisabledNudgeId[] =
|
||||
"video_conference_tray_nudge_ids.camera_microphone_use_while_disabled";
|
||||
|
||||
// VC nudge ids vector that is iterated whenever `CloseAllVcNudges()` is
|
||||
// called. Please keep in sync whenever adding/removing/updating a nudge id.
|
||||
@ -82,6 +84,7 @@ const char* const kNudgeIds[] = {
|
||||
constexpr int KSpeakOnMuteNotificationCoolDownDuration = 60;
|
||||
|
||||
constexpr auto kRepeatedShowTimerInterval = base::Milliseconds(100);
|
||||
constexpr auto kHandleDeviceUsedWhileDisabledWaitTime = base::Milliseconds(200);
|
||||
|
||||
// The max amount of times the "Speak-on-mute opt-in" nudge can show.
|
||||
constexpr int kSpeakOnMuteOptInNudgeMaxShownCount = 3;
|
||||
@ -430,10 +433,15 @@ void VideoConferenceTrayController::OnCameraHWPrivacySwitchStateChanged(
|
||||
|
||||
// Attempt recording "Use while disabled" nudge action when camera is unmuted.
|
||||
if (!camera_muted_by_hardware_switch_) {
|
||||
AnchoredNudgeManager::Get()->MaybeRecordNudgeAction(
|
||||
auto* nudge_manager = AnchoredNudgeManager::Get();
|
||||
|
||||
nudge_manager->MaybeRecordNudgeAction(
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraUseWhileHWDisabled);
|
||||
AnchoredNudgeManager::Get()->Cancel(
|
||||
kVideoConferenceTrayCameraUseWhileHWDisabledNudgeId);
|
||||
nudge_manager->Cancel(kVideoConferenceTrayCameraUseWhileHWDisabledNudgeId);
|
||||
|
||||
nudge_manager->MaybeRecordNudgeAction(
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraMicrophoneUseWhileDisabled);
|
||||
nudge_manager->Cancel(kVideoConferenceTrayBothUseWhileDisabledNudgeId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -452,10 +460,15 @@ void VideoConferenceTrayController::OnCameraSWPrivacySwitchStateChanged(
|
||||
|
||||
// Attempt recording "Use while disabled" nudge action when camera is unmuted.
|
||||
if (!camera_muted_by_software_switch_) {
|
||||
AnchoredNudgeManager::Get()->MaybeRecordNudgeAction(
|
||||
auto* nudge_manager = AnchoredNudgeManager::Get();
|
||||
|
||||
nudge_manager->MaybeRecordNudgeAction(
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraUseWhileSWDisabled);
|
||||
AnchoredNudgeManager::Get()->Cancel(
|
||||
kVideoConferenceTrayCameraUseWhileSWDisabledNudgeId);
|
||||
nudge_manager->Cancel(kVideoConferenceTrayCameraUseWhileSWDisabledNudgeId);
|
||||
|
||||
nudge_manager->MaybeRecordNudgeAction(
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraMicrophoneUseWhileDisabled);
|
||||
nudge_manager->Cancel(kVideoConferenceTrayBothUseWhileDisabledNudgeId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -494,26 +507,30 @@ void VideoConferenceTrayController::OnInputMuteChanged(
|
||||
// Attempt showing the speak-on-mute opt-in nudge when input is muted.
|
||||
MaybeShowSpeakOnMuteOptInNudge(GetVcTrayInActiveWindow());
|
||||
} else {
|
||||
auto* nudge_manager = AnchoredNudgeManager::Get();
|
||||
|
||||
// Cancel speak-on-mute opt-in nudge if one was being shown.
|
||||
AnchoredNudgeManager::Get()->Cancel(
|
||||
kVideoConferenceTraySpeakOnMuteOptInNudgeId);
|
||||
nudge_manager->Cancel(kVideoConferenceTraySpeakOnMuteOptInNudgeId);
|
||||
|
||||
// Attempt recording "Speak-on-mute" nudge action when mic is unmuted.
|
||||
AnchoredNudgeManager::Get()->MaybeRecordNudgeAction(
|
||||
nudge_manager->MaybeRecordNudgeAction(
|
||||
NudgeCatalogName::kVideoConferenceTraySpeakOnMuteDetected);
|
||||
AnchoredNudgeManager::Get()->Cancel(
|
||||
kVideoConferenceTraySpeakOnMuteDetectedNudgeId);
|
||||
nudge_manager->Cancel(kVideoConferenceTraySpeakOnMuteDetectedNudgeId);
|
||||
|
||||
// Attempt recording "Use while disabled" nudge action when mic is unmuted.
|
||||
AnchoredNudgeManager::Get()->MaybeRecordNudgeAction(
|
||||
nudge_manager->MaybeRecordNudgeAction(
|
||||
microphone_muted_by_hardware_switch_
|
||||
? NudgeCatalogName::kVideoConferenceTrayMicrophoneUseWhileHWDisabled
|
||||
: NudgeCatalogName::
|
||||
kVideoConferenceTrayMicrophoneUseWhileSWDisabled);
|
||||
AnchoredNudgeManager::Get()->Cancel(
|
||||
nudge_manager->Cancel(
|
||||
microphone_muted_by_hardware_switch_
|
||||
? kVideoConferenceTrayMicrophoneUseWhileHWDisabledNudgeId
|
||||
: kVideoConferenceTrayMicrophoneUseWhileSWDisabledNudgeId);
|
||||
|
||||
nudge_manager->MaybeRecordNudgeAction(
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraMicrophoneUseWhileDisabled);
|
||||
nudge_manager->Cancel(kVideoConferenceTrayBothUseWhileDisabledNudgeId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -677,62 +694,34 @@ bool VideoConferenceTrayController::HasMicrophonePermission() const {
|
||||
void VideoConferenceTrayController::HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice device,
|
||||
const std::u16string& app_name) {
|
||||
// Do not show "Use while disabled" nudge if another nudge is showing.
|
||||
if (IsAnyVcNudgeShown()) {
|
||||
if (device == crosapi::mojom::VideoConferenceMediaDevice::kUnusedDefault) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(b/273570886): Handle the case when both camera and microphone are
|
||||
// being used while disabled.
|
||||
std::u16string device_name;
|
||||
int text_id;
|
||||
NudgeCatalogName catalog_name;
|
||||
std::string nudge_id;
|
||||
views::View* anchor_view = nullptr;
|
||||
switch (device) {
|
||||
case crosapi::mojom::VideoConferenceMediaDevice::kMicrophone:
|
||||
device_name =
|
||||
l10n_util::GetStringUTF16(IDS_ASH_VIDEO_CONFERENCE_MICROPHONE_NAME);
|
||||
if (microphone_muted_by_hardware_switch_) {
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_HARDWARE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayMicrophoneUseWhileHWDisabledNudgeId;
|
||||
catalog_name =
|
||||
NudgeCatalogName::kVideoConferenceTrayMicrophoneUseWhileHWDisabled;
|
||||
} else {
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_SOFTWARE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayMicrophoneUseWhileSWDisabledNudgeId;
|
||||
catalog_name =
|
||||
NudgeCatalogName::kVideoConferenceTrayMicrophoneUseWhileSWDisabled;
|
||||
}
|
||||
anchor_view = GetVcTrayInActiveWindow()->audio_icon();
|
||||
break;
|
||||
case crosapi::mojom::VideoConferenceMediaDevice::kCamera:
|
||||
device_name =
|
||||
l10n_util::GetStringUTF16(IDS_ASH_VIDEO_CONFERENCE_CAMERA_NAME);
|
||||
if (camera_muted_by_hardware_switch_) {
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_HARDWARE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayCameraUseWhileHWDisabledNudgeId;
|
||||
catalog_name =
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraUseWhileHWDisabled;
|
||||
} else {
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_SOFTWARE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayCameraUseWhileSWDisabledNudgeId;
|
||||
catalog_name =
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraUseWhileSWDisabled;
|
||||
}
|
||||
anchor_view = GetVcTrayInActiveWindow()->camera_icon();
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
return;
|
||||
UsedWhileDisabledNudgeType type = GetUsedWhileDisabledNudgeType(device);
|
||||
|
||||
if (!use_while_disabled_signal_waiter_.IsRunning()) {
|
||||
// Cache the type and starts the timer to wait for the signal of the other
|
||||
// device.
|
||||
use_while_disabled_nudge_on_wait_ = type;
|
||||
|
||||
use_while_disabled_signal_waiter_.Start(
|
||||
FROM_HERE, kHandleDeviceUsedWhileDisabledWaitTime,
|
||||
base::BindOnce(
|
||||
&VideoConferenceTrayController::DisplayUsedWhileDisabledNudge,
|
||||
weak_ptr_factory_.GetWeakPtr(), type, app_name));
|
||||
return;
|
||||
}
|
||||
|
||||
AnchoredNudgeData nudge_data(
|
||||
nudge_id, catalog_name,
|
||||
l10n_util::GetStringFUTF16(text_id, app_name, device_name), anchor_view);
|
||||
nudge_data.anchored_to_shelf = true;
|
||||
CreateNudgeRequest(
|
||||
std::make_unique<AnchoredNudgeData>(std::move(nudge_data)));
|
||||
if (type == use_while_disabled_nudge_on_wait_) {
|
||||
return;
|
||||
}
|
||||
|
||||
use_while_disabled_signal_waiter_.Stop();
|
||||
|
||||
// If we receive the signal for both camera and microphone, display the nudge
|
||||
// for both.
|
||||
DisplayUsedWhileDisabledNudge(UsedWhileDisabledNudgeType::kBoth, app_name);
|
||||
}
|
||||
|
||||
void VideoConferenceTrayController::UpdateCameraIcons() {
|
||||
@ -797,4 +786,94 @@ void VideoConferenceTrayController::RecordRepeatedShows() {
|
||||
count_repeated_shows_ = 0;
|
||||
}
|
||||
|
||||
void VideoConferenceTrayController::DisplayUsedWhileDisabledNudge(
|
||||
VideoConferenceTrayController::UsedWhileDisabledNudgeType type,
|
||||
const std::u16string& app_name) {
|
||||
// Do not show "Use while disabled" nudge if another nudge is showing.
|
||||
if (IsAnyVcNudgeShown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::u16string device_name;
|
||||
int text_id;
|
||||
NudgeCatalogName catalog_name;
|
||||
std::string nudge_id;
|
||||
views::View* anchor_view = nullptr;
|
||||
switch (type) {
|
||||
case VideoConferenceTrayController::UsedWhileDisabledNudgeType::kMicrophone:
|
||||
device_name =
|
||||
l10n_util::GetStringUTF16(IDS_ASH_VIDEO_CONFERENCE_MICROPHONE_NAME);
|
||||
if (microphone_muted_by_hardware_switch_) {
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_HARDWARE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayMicrophoneUseWhileHWDisabledNudgeId;
|
||||
catalog_name =
|
||||
NudgeCatalogName::kVideoConferenceTrayMicrophoneUseWhileHWDisabled;
|
||||
} else {
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayMicrophoneUseWhileSWDisabledNudgeId;
|
||||
catalog_name =
|
||||
NudgeCatalogName::kVideoConferenceTrayMicrophoneUseWhileSWDisabled;
|
||||
}
|
||||
anchor_view = GetVcTrayInActiveWindow()->audio_icon();
|
||||
break;
|
||||
case VideoConferenceTrayController::UsedWhileDisabledNudgeType::kCamera:
|
||||
device_name =
|
||||
l10n_util::GetStringUTF16(IDS_ASH_VIDEO_CONFERENCE_CAMERA_NAME);
|
||||
if (camera_muted_by_hardware_switch_) {
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_HARDWARE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayCameraUseWhileHWDisabledNudgeId;
|
||||
catalog_name =
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraUseWhileHWDisabled;
|
||||
} else {
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayCameraUseWhileSWDisabledNudgeId;
|
||||
catalog_name =
|
||||
NudgeCatalogName::kVideoConferenceTrayCameraUseWhileSWDisabled;
|
||||
}
|
||||
anchor_view = GetVcTrayInActiveWindow()->camera_icon();
|
||||
break;
|
||||
case VideoConferenceTrayController::UsedWhileDisabledNudgeType::kBoth:
|
||||
device_name = l10n_util::GetStringUTF16(
|
||||
IDS_ASH_VIDEO_CONFERENCE_CAMERA_MICROPHONE_NAME);
|
||||
text_id = IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED;
|
||||
nudge_id = kVideoConferenceTrayBothUseWhileDisabledNudgeId;
|
||||
catalog_name = NudgeCatalogName::
|
||||
kVideoConferenceTrayCameraMicrophoneUseWhileDisabled;
|
||||
anchor_view = GetVcTrayInActiveWindow()->audio_icon();
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
AnchoredNudgeData nudge_data(
|
||||
nudge_id, catalog_name,
|
||||
l10n_util::GetStringFUTF16(text_id, app_name, device_name), anchor_view);
|
||||
nudge_data.anchored_to_shelf = true;
|
||||
CreateNudgeRequest(
|
||||
std::make_unique<AnchoredNudgeData>(std::move(nudge_data)));
|
||||
}
|
||||
|
||||
VideoConferenceTrayController::UsedWhileDisabledNudgeType
|
||||
VideoConferenceTrayController::GetUsedWhileDisabledNudgeType(
|
||||
crosapi::mojom::VideoConferenceMediaDevice device) {
|
||||
DCHECK_NE(device, crosapi::mojom::VideoConferenceMediaDevice::kUnusedDefault);
|
||||
|
||||
VideoConferenceTrayController::UsedWhileDisabledNudgeType type;
|
||||
switch (device) {
|
||||
case crosapi::mojom::VideoConferenceMediaDevice::kCamera:
|
||||
type = VideoConferenceTrayController::UsedWhileDisabledNudgeType::kCamera;
|
||||
break;
|
||||
case crosapi::mojom::VideoConferenceMediaDevice::kMicrophone:
|
||||
type = VideoConferenceTrayController::UsedWhileDisabledNudgeType::
|
||||
kMicrophone;
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
type = VideoConferenceTrayController::UsedWhileDisabledNudgeType::kCamera;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
} // namespace ash
|
||||
|
@ -201,6 +201,14 @@ class ASH_EXPORT VideoConferenceTrayController
|
||||
bool initialized() const { return initialized_; }
|
||||
|
||||
private:
|
||||
// All the types of the use while disabled nudge.
|
||||
enum class UsedWhileDisabledNudgeType {
|
||||
kCamera = 0,
|
||||
kMicrophone = 1,
|
||||
kBoth = 2,
|
||||
kMaxValue = kBoth
|
||||
};
|
||||
|
||||
// Updates the state of the camera icons across all `VideoConferenceTray`.
|
||||
void UpdateCameraIcons();
|
||||
|
||||
@ -214,6 +222,13 @@ class ASH_EXPORT VideoConferenceTrayController
|
||||
// Returns true if any of the VC nudges are visible on screen.
|
||||
bool IsAnyVcNudgeShown();
|
||||
|
||||
// Displays the use while disabled nudge according to the given `type`.
|
||||
void DisplayUsedWhileDisabledNudge(UsedWhileDisabledNudgeType type,
|
||||
const std::u16string& app_name);
|
||||
|
||||
UsedWhileDisabledNudgeType GetUsedWhileDisabledNudgeType(
|
||||
crosapi::mojom::VideoConferenceMediaDevice device);
|
||||
|
||||
// The number of capturing apps, fetched from `VideoConferenceManagerAsh`.
|
||||
int capturing_apps_ = 0;
|
||||
|
||||
@ -268,6 +283,14 @@ class ASH_EXPORT VideoConferenceTrayController
|
||||
int count_repeated_shows_ = 0;
|
||||
base::DelayTimer repeated_shows_timer_;
|
||||
|
||||
// Due to some constraint in `VideoConferenceManagerAsh`, when both microphone
|
||||
// and camera is being accessed when disabled,`HandleDeviceUsedWhileDisabled`
|
||||
// will be called twice for each device. Thus, we need to wait for both 2
|
||||
// calls and display one nudge for both. These are the timer and the cache
|
||||
// type to make that happen.
|
||||
base::OneShotTimer use_while_disabled_signal_waiter_;
|
||||
UsedWhileDisabledNudgeType use_while_disabled_nudge_on_wait_;
|
||||
|
||||
// The contents of a nudge data object that is cached so it can be shown once
|
||||
// the tray has fully animated in.
|
||||
std::unique_ptr<AnchoredNudgeData> requested_nudge_data_;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "base/test/metrics/histogram_tester.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "base/time/time.h"
|
||||
#include "chromeos/ash/components/audio/cras_audio_handler.h"
|
||||
#include "chromeos/crosapi/mojom/video_conference.mojom.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
@ -51,10 +52,14 @@ constexpr char kVideoConferenceTrayCameraUseWhileHWDisabledNudgeId[] =
|
||||
"video_conference_tray_nudge_ids.camera_use_while_hw_disabled";
|
||||
constexpr char kVideoConferenceTrayCameraUseWhileSWDisabledNudgeId[] =
|
||||
"video_conference_tray_nudge_ids.camera_use_while_sw_disabled";
|
||||
constexpr char kVideoConferenceTrayBothUseWhileDisabledNudgeId[] =
|
||||
"video_conference_tray_nudge_ids.camera_microphone_use_while_disabled";
|
||||
|
||||
constexpr char kRepeatedShowsHistogramName[] =
|
||||
"Ash.VideoConference.NumberOfRepeatedShows";
|
||||
|
||||
constexpr auto kHandleDeviceUsedWhileDisabledWaitTime = base::Milliseconds(200);
|
||||
|
||||
bool IsNudgeShown(const std::string& id) {
|
||||
return Shell::Get()->anchored_nudge_manager()->IsNudgeShown(id);
|
||||
}
|
||||
@ -261,14 +266,15 @@ TEST_F(VideoConferenceTrayControllerTest,
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kCamera, app_name);
|
||||
|
||||
// Nudge should be displayed. Showing that app is accessing while camera is
|
||||
// software-muted.
|
||||
// After `kHandleDeviceUsedWhileDisabledWaitTime`, nudge should be displayed.
|
||||
// Showing that app is accessing while camera is software-muted.
|
||||
task_environment()->FastForwardBy(kHandleDeviceUsedWhileDisabledWaitTime);
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
EXPECT_EQ(GetNudgeAnchorView(nudge_id), camera_icon());
|
||||
EXPECT_EQ(GetNudgeText(nudge_id),
|
||||
l10n_util::GetStringFUTF16(
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_SOFTWARE_DISABLED,
|
||||
app_name, camera_device_name));
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED, app_name,
|
||||
camera_device_name));
|
||||
|
||||
// Unmute camera through SW. Nudge should be dismissed.
|
||||
controller()->OnCameraSWPrivacySwitchStateChanged(
|
||||
@ -294,14 +300,15 @@ TEST_F(VideoConferenceTrayControllerTest,
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, app_name);
|
||||
|
||||
// Nudge should be displayed. Showing that app is accessing while microphone
|
||||
// is software-muted.
|
||||
// After `kHandleDeviceUsedWhileDisabledWaitTime`, nudge should be displayed.
|
||||
// Showing that app is accessing while microphone is software-muted.
|
||||
task_environment()->FastForwardBy(kHandleDeviceUsedWhileDisabledWaitTime);
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
EXPECT_EQ(GetNudgeAnchorView(nudge_id), audio_icon());
|
||||
EXPECT_EQ(GetNudgeText(nudge_id),
|
||||
l10n_util::GetStringFUTF16(
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_SOFTWARE_DISABLED,
|
||||
app_name, microphone_device_name));
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED, app_name,
|
||||
microphone_device_name));
|
||||
|
||||
// Unmute microphone through SW. Nudge should be dismissed.
|
||||
controller()->OnInputMuteChanged(
|
||||
@ -327,8 +334,9 @@ TEST_F(VideoConferenceTrayControllerTest,
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kCamera, app_name);
|
||||
|
||||
// Nudge should be displayed. Showing that app is accessing while camera is
|
||||
// hardware-muted.
|
||||
// After `kHandleDeviceUsedWhileDisabledWaitTime`, nudge should be displayed.
|
||||
// Showing that app is accessing while camera is hardware-muted.
|
||||
task_environment()->FastForwardBy(kHandleDeviceUsedWhileDisabledWaitTime);
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
EXPECT_EQ(GetNudgeAnchorView(nudge_id), camera_icon());
|
||||
EXPECT_EQ(GetNudgeText(nudge_id),
|
||||
@ -361,8 +369,9 @@ TEST_F(VideoConferenceTrayControllerTest,
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, app_name);
|
||||
|
||||
// Nudge should be displayed. Showing that app is accessing while microphone
|
||||
// is hardware-muted.
|
||||
// After `kHandleDeviceUsedWhileDisabledWaitTime`, nudge should be displayed.
|
||||
// Showing that app is accessing while microphone is hardware-muted.
|
||||
task_environment()->FastForwardBy(kHandleDeviceUsedWhileDisabledWaitTime);
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
EXPECT_EQ(GetNudgeAnchorView(nudge_id), audio_icon());
|
||||
EXPECT_EQ(GetNudgeText(nudge_id),
|
||||
@ -377,6 +386,110 @@ TEST_F(VideoConferenceTrayControllerTest,
|
||||
EXPECT_FALSE(IsNudgeShown(nudge_id));
|
||||
}
|
||||
|
||||
TEST_F(VideoConferenceTrayControllerTest,
|
||||
HandleCameraMicrophoneUsedWhileDisabled) {
|
||||
auto* app_name = u"app_name";
|
||||
auto device_name = l10n_util::GetStringUTF16(
|
||||
IDS_ASH_VIDEO_CONFERENCE_CAMERA_MICROPHONE_NAME);
|
||||
auto* nudge_id = kVideoConferenceTrayBothUseWhileDisabledNudgeId;
|
||||
|
||||
SetTrayAndButtonsVisible();
|
||||
|
||||
controller()->OnInputMuteChanged(
|
||||
/*mute_on=*/true, CrasAudioHandler::InputMuteChangeMethod::kOther);
|
||||
controller()->OnCameraHWPrivacySwitchStateChanged(
|
||||
/*device_id=*/"device_id", cros::mojom::CameraPrivacySwitchState::ON);
|
||||
|
||||
// No nudge is shown before `HandleDeviceUsedWhileDisabled()` is called.
|
||||
EXPECT_FALSE(IsNudgeShown(nudge_id));
|
||||
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, app_name);
|
||||
|
||||
task_environment()->FastForwardBy(base::Milliseconds(20));
|
||||
|
||||
// No nudge is shown yet since we are waiting for more signal for
|
||||
// `HandleDeviceUsedWhileDisabled`.
|
||||
EXPECT_FALSE(IsNudgeShown(nudge_id));
|
||||
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kCamera, app_name);
|
||||
|
||||
// Nudge should be displayed when receiving signal for both camera and
|
||||
// microphone.
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
EXPECT_EQ(GetNudgeAnchorView(nudge_id), audio_icon());
|
||||
EXPECT_EQ(GetNudgeText(nudge_id),
|
||||
l10n_util::GetStringFUTF16(
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED, app_name,
|
||||
device_name));
|
||||
}
|
||||
|
||||
TEST_F(VideoConferenceTrayControllerTest,
|
||||
UnmuteCameraWithCameraMicrophoneUsedWhileDisabledNudge) {
|
||||
auto* app_name = u"app_name";
|
||||
auto* nudge_id = kVideoConferenceTrayBothUseWhileDisabledNudgeId;
|
||||
|
||||
SetTrayAndButtonsVisible();
|
||||
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, app_name);
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kCamera, app_name);
|
||||
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
|
||||
// Now unmute camera. Nudge should also be dismissed.
|
||||
controller()->OnCameraSWPrivacySwitchStateChanged(
|
||||
cros::mojom::CameraPrivacySwitchState::OFF);
|
||||
EXPECT_FALSE(IsNudgeShown(nudge_id));
|
||||
|
||||
// Test the same thing for hw-unmuting camera.
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, app_name);
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kCamera, app_name);
|
||||
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
|
||||
controller()->OnCameraHWPrivacySwitchStateChanged(
|
||||
/*device_id=*/"device_id", cros::mojom::CameraPrivacySwitchState::OFF);
|
||||
EXPECT_FALSE(IsNudgeShown(nudge_id));
|
||||
}
|
||||
|
||||
TEST_F(VideoConferenceTrayControllerTest,
|
||||
UnmuteMicrophoneWithCameraMicrophoneUsedWhileDisabledNudge) {
|
||||
auto* app_name = u"app_name";
|
||||
auto* nudge_id = kVideoConferenceTrayBothUseWhileDisabledNudgeId;
|
||||
|
||||
SetTrayAndButtonsVisible();
|
||||
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, app_name);
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kCamera, app_name);
|
||||
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
|
||||
// Now unmute microphone. Nudge should also be dismissed.
|
||||
controller()->OnInputMuteChanged(
|
||||
/*mute_on=*/false, CrasAudioHandler::InputMuteChangeMethod::kOther);
|
||||
EXPECT_FALSE(IsNudgeShown(nudge_id));
|
||||
|
||||
// Test the same thing for hw-unmuting microphone.
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, app_name);
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kCamera, app_name);
|
||||
|
||||
ASSERT_TRUE(IsNudgeShown(nudge_id));
|
||||
|
||||
controller()->OnInputMuteChanged(
|
||||
/*mute_on=*/false,
|
||||
CrasAudioHandler::InputMuteChangeMethod::kPhysicalShutter);
|
||||
EXPECT_FALSE(IsNudgeShown(nudge_id));
|
||||
}
|
||||
|
||||
TEST_F(VideoConferenceTrayControllerTest, SpeakOnMuteNudge) {
|
||||
auto* nudge_id = kVideoConferenceTraySpeakOnMuteDetectedNudgeId;
|
||||
|
||||
@ -673,6 +786,7 @@ TEST_F(VideoConferenceTrayControllerTest, NudgeBlocksOtherNudges) {
|
||||
/*device_id=*/"device_id", cros::mojom::CameraPrivacySwitchState::ON);
|
||||
controller()->HandleDeviceUsedWhileDisabled(
|
||||
crosapi::mojom::VideoConferenceMediaDevice::kCamera, app_name);
|
||||
task_environment()->FastForwardBy(kHandleDeviceUsedWhileDisabledWaitTime);
|
||||
EXPECT_TRUE(IsNudgeShown(use_while_disabled_nudge_id));
|
||||
|
||||
// Show opt-in nudge by muting the microphone, "use while disabled" nudge
|
||||
|
@ -681,7 +681,7 @@ IN_PROC_BROWSER_TEST_P(VideoConferenceIntegrationTest, UseWhileDisabled) {
|
||||
EXPECT_EQ(
|
||||
GetNudgeText(microphone_nudge_id),
|
||||
l10n_util::GetStringFUTF16(
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_SOFTWARE_DISABLED, kTitle1,
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED, kTitle1,
|
||||
l10n_util::GetStringUTF16(IDS_ASH_VIDEO_CONFERENCE_MICROPHONE_NAME)));
|
||||
EXPECT_EQ(GetNudgeAnchorView(microphone_nudge_id), GetVcTray()->audio_icon());
|
||||
|
||||
@ -703,7 +703,7 @@ IN_PROC_BROWSER_TEST_P(VideoConferenceIntegrationTest, UseWhileDisabled) {
|
||||
EXPECT_EQ(
|
||||
GetNudgeText(camera_nudge_id),
|
||||
l10n_util::GetStringFUTF16(
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_SOFTWARE_DISABLED, kTitle1,
|
||||
IDS_ASH_VIDEO_CONFERENCE_TOAST_USE_WHILE_DISABLED, kTitle1,
|
||||
l10n_util::GetStringUTF16(IDS_ASH_VIDEO_CONFERENCE_CAMERA_NAME)));
|
||||
EXPECT_EQ(GetNudgeAnchorView(camera_nudge_id), GetVcTray()->camera_icon());
|
||||
}
|
||||
|
@ -77094,6 +77094,8 @@ Called by update_net_trust_anchors.py.-->
|
||||
<int value="17"
|
||||
label="Video Conference Tray Speak On Mute Opt In Confirmation"/>
|
||||
<int value="18" label="Scalable IPH Bubble"/>
|
||||
<int value="19"
|
||||
label="Video Conference Tray Camera And Microphone Use While Disabled"/>
|
||||
</enum>
|
||||
|
||||
<enum name="NukeProfileResult">
|
||||
|
Reference in New Issue
Block a user