0

Add tooltip to device counter in page info and permission prompt

The tooltip would be a list of real devices.

This change would only affects Win/Mac/Linux when `#camera-mic-preview`
flag is enabled

Bug: b:329860004
Change-Id: I4657a4b10aaa5510e3210bf9709e6eb794222e24
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5370766
Reviewed-by: Mustafa Emre Acer <meacer@chromium.org>
Reviewed-by: Thomas Nguyen <tungnh@chromium.org>
Auto-Submit: Ahmed Moussa <ahmedmoussa@google.com>
Commit-Queue: Ahmed Moussa <ahmedmoussa@google.com>
Reviewed-by: Bryant Chandler <bryantchandler@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1273832}
This commit is contained in:
ahmedmoussa
2024-03-16 16:15:26 +00:00
committed by Chromium LUCI CQ
parent f6660b7428
commit 5b526e95ae
6 changed files with 90 additions and 27 deletions

@ -9,6 +9,7 @@
#include "base/metrics/histogram_functions.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/file_system_access/chrome_file_system_access_permission_context.h"
#include "chrome/browser/file_system_access/file_system_access_features.h"
#include "chrome/browser/file_system_access/file_system_access_permission_context_factory.h"
@ -270,10 +271,9 @@ void PageInfoPermissionContentView::OnAudioDevicesChanged(
const std::optional<std::vector<media::AudioDeviceDescription>>&
device_infos) {
if (type_ == ContentSettingsType::MEDIASTREAM_MIC && device_infos) {
title_->SetText(l10n_util::GetStringFUTF16(
SetTitleTextAndTooltip(
IDS_SITE_SETTINGS_TYPE_MIC_WITH_COUNT,
base::NumberToString16(
media_effects::GetRealAudioDeviceCount(device_infos.value()))));
media_effects::GetRealAudioDeviceNames(device_infos.value()));
}
}
@ -281,11 +281,20 @@ void PageInfoPermissionContentView::OnVideoDevicesChanged(
const std::optional<std::vector<media::VideoCaptureDeviceInfo>>&
device_infos) {
if (type_ == ContentSettingsType::MEDIASTREAM_CAMERA && device_infos) {
title_->SetText(l10n_util::GetStringFUTF16(
SetTitleTextAndTooltip(
IDS_SITE_SETTINGS_TYPE_CAMERA_WITH_COUNT,
base::NumberToString16(device_infos->size())));
media_effects::GetRealVideoDeviceNames(device_infos.value()));
}
}
void PageInfoPermissionContentView::SetTitleTextAndTooltip(
int message_id,
const std::vector<std::string>& device_names) {
title_->SetText(l10n_util::GetStringFUTF16(
message_id, base::NumberToString16(device_names.size())));
title_->SetTooltipText(
base::UTF8ToUTF16(base::JoinString(device_names, "\n")));
}
#endif
void PageInfoPermissionContentView::ToggleFileSystemExtendedPermissions() {

@ -86,6 +86,8 @@ class PageInfoPermissionContentView
void OnVideoDevicesChanged(
const std::optional<std::vector<media::VideoCaptureDeviceInfo>>&
device_infos) override;
void SetTitleTextAndTooltip(int message_id,
const std::vector<std::string>& device_names);
#endif
// Adds Media (Camera or Mic) live preview feeds.

@ -29,6 +29,7 @@
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/media_effects/media_device_info.h"
#include "components/permissions/features.h"
#include "components/permissions/permission_request.h"
#include "components/permissions/permission_uma_util.h"
@ -316,21 +317,36 @@ void PermissionPromptBubbleOneOriginView::MaybeAddMediaPreview(
void PermissionPromptBubbleOneOriginView::OnAudioDevicesChanged(
const std::optional<std::vector<media::AudioDeviceDescription>>&
device_infos) {
if (mic_permission_label_ && device_infos) {
mic_permission_label_->SetText(l10n_util::GetStringFUTF16(
IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT_WITH_COUNT,
base::NumberToString16(
media_effects::GetRealAudioDeviceCount(device_infos.value()))));
if (!mic_permission_label_ || !device_infos) {
return;
}
const auto real_device_names =
media_effects::GetRealAudioDeviceNames(device_infos.value());
mic_permission_label_->SetText(l10n_util::GetStringFUTF16(
IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT_WITH_COUNT,
base::NumberToString16(real_device_names.size())));
mic_permission_label_->SetTooltipText(
base::UTF8ToUTF16(base::JoinString(real_device_names, "\n")));
}
void PermissionPromptBubbleOneOriginView::OnVideoDevicesChanged(
const std::optional<std::vector<media::VideoCaptureDeviceInfo>>&
device_infos) {
if (camera_permission_label_ && device_infos) {
camera_permission_label_->SetText(l10n_util::GetStringFUTF16(
IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT_WITH_COUNT,
base::NumberToString16(device_infos->size())));
if (!camera_permission_label_ || !device_infos) {
return;
}
const auto real_device_names =
media_effects::GetRealVideoDeviceNames(device_infos.value());
camera_permission_label_->SetText(l10n_util::GetStringFUTF16(
IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT_WITH_COUNT,
base::NumberToString16(real_device_names.size())));
camera_permission_label_->SetTooltipText(
base::UTF8ToUTF16(base::JoinString(real_device_names, "\n")));
}
#endif

@ -26,17 +26,26 @@ std::optional<std::string> GetRealDefaultDeviceId(
return std::nullopt;
}
size_t GetRealAudioDeviceCount(
std::vector<std::string> GetRealAudioDeviceNames(
const std::vector<media::AudioDeviceDescription>& infos) {
size_t device_count = 0;
std::vector<std::string> real_names;
for (const auto& info : infos) {
if (!media::AudioDeviceDescription::IsDefaultDevice(info.unique_id) &&
!media::AudioDeviceDescription::IsCommunicationsDevice(
info.unique_id)) {
++device_count;
real_names.push_back(info.device_name);
}
}
return device_count;
return real_names;
}
std::vector<std::string> GetRealVideoDeviceNames(
const std::vector<media::VideoCaptureDeviceInfo>& infos) {
std::vector<std::string> names;
for (const auto& info : infos) {
names.push_back(info.descriptor.GetNameAndModel());
}
return names;
}
MediaDeviceInfo::MediaDeviceInfo() {

@ -18,10 +18,15 @@ namespace media_effects {
std::optional<std::string> GetRealDefaultDeviceId(
const std::vector<media::AudioDeviceDescription>& infos);
// Returns the real number of mics by excluding virtual devices such as default.
size_t GetRealAudioDeviceCount(
// Returns a list of the real mics names by excluding virtual devices such as
// default.
std::vector<std::string> GetRealAudioDeviceNames(
const std::vector<media::AudioDeviceDescription>& infos);
// Returns a list of the cameras names.
std::vector<std::string> GetRealVideoDeviceNames(
const std::vector<media::VideoCaptureDeviceInfo>& infos);
// This class manages a cache of device infos for currently connected audio and
// video capture devices. It is similar to `MediaCaptureDevicesImpl` from
// content, but it holds the media::types instead of blink::MediaStreamDevice.

@ -18,8 +18,9 @@
namespace {
using media_effects::GetRealAudioDeviceCount;
using media_effects::GetRealAudioDeviceNames;
using media_effects::GetRealDefaultDeviceId;
using media_effects::GetRealVideoDeviceNames;
media::AudioDeviceDescription GetAudioDeviceDescription(size_t index) {
return media::AudioDeviceDescription{
@ -236,27 +237,48 @@ TEST_F(MediaDeviceInfoTest, Observers) {
TEST(MediaDeviceInfoTestGeneral, DefaultAudioDeviceHandling) {
std::vector<media::AudioDeviceDescription> infos;
EXPECT_EQ(GetRealDefaultDeviceId(infos), std::nullopt);
EXPECT_EQ(GetRealAudioDeviceCount(infos), 0u);
EXPECT_EQ(GetRealAudioDeviceNames(infos).size(), 0u);
infos.push_back(GetAudioDeviceDescription(0));
infos.push_back(GetAudioDeviceDescription(1));
infos.push_back(GetAudioDeviceDescription(2));
EXPECT_EQ(GetRealDefaultDeviceId(infos), std::nullopt);
EXPECT_EQ(GetRealAudioDeviceCount(infos), 3u);
EXPECT_THAT(GetRealAudioDeviceNames(infos),
testing::ElementsAre(infos[0].device_name, infos[1].device_name,
infos[2].device_name));
infos.front().is_system_default = true;
EXPECT_EQ(GetRealDefaultDeviceId(infos), infos.front().unique_id);
EXPECT_EQ(GetRealAudioDeviceCount(infos), 3u);
EXPECT_THAT(GetRealAudioDeviceNames(infos),
testing::ElementsAre(infos[0].device_name, infos[1].device_name,
infos[2].device_name));
infos.front().unique_id = media::AudioDeviceDescription::kDefaultDeviceId;
EXPECT_EQ(GetRealDefaultDeviceId(infos), std::nullopt);
EXPECT_EQ(GetRealAudioDeviceCount(infos), 2u);
EXPECT_THAT(GetRealAudioDeviceNames(infos),
testing::ElementsAre(infos[1].device_name, infos[2].device_name));
infos[1].is_system_default = true;
EXPECT_EQ(GetRealDefaultDeviceId(infos), infos[1].unique_id);
EXPECT_EQ(GetRealAudioDeviceCount(infos), 2u);
EXPECT_THAT(GetRealAudioDeviceNames(infos),
testing::ElementsAre(infos[1].device_name, infos[2].device_name));
infos[2].unique_id = media::AudioDeviceDescription::kCommunicationsDeviceId;
EXPECT_EQ(GetRealDefaultDeviceId(infos), infos[1].unique_id);
EXPECT_EQ(GetRealAudioDeviceCount(infos), 1u);
EXPECT_THAT(GetRealAudioDeviceNames(infos),
testing::ElementsAre(infos[1].device_name));
}
TEST(MediaDeviceInfoTestGeneral, GetVideoDeviceNames) {
std::vector<media::VideoCaptureDeviceInfo> infos;
EXPECT_EQ(GetRealVideoDeviceNames(infos).size(), 0u);
infos.emplace_back(GetVideoCaptureDeviceDescriptor(0));
infos.emplace_back(GetVideoCaptureDeviceDescriptor(1));
infos.emplace_back(GetVideoCaptureDeviceDescriptor(2));
EXPECT_THAT(GetRealVideoDeviceNames(infos),
testing::ElementsAre(infos[0].descriptor.GetNameAndModel(),
infos[1].descriptor.GetNameAndModel(),
infos[2].descriptor.GetNameAndModel()));
}