blob: 5528fae844da534bbf47e6c9a2a3046fa4a0ed36 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/media/media_devices_util.h"
#include "media/audio/audio_device_description.h"
#include "media/capture/video/video_capture_device_descriptor.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/mediastream/media_devices.h"
#include "url/gurl.h"
namespace content {
using ::blink::mojom::MediaDeviceType;
using ::blink::mojom::MediaStreamType;
using ::testing::Eq;
using ::testing::Optional;
namespace {
MediaDeviceSaltAndOrigin ExampleSaltAndOrigin() {
return MediaDeviceSaltAndOrigin(
"Device ID Salt", url::Origin::Create(GURL("https://example.com")),
"Group ID Salt");
}
blink::WebMediaDeviceInfo ExampleWebMediaDeviceInfo() {
return blink::WebMediaDeviceInfo(
/*device_id=*/"example device id",
/*label=*/"example label",
/*group_id=*/"example_group_id",
/*video_control_support=*/{.pan = true, .tilt = true, .zoom = true},
blink::mojom::FacingMode::kEnvironment,
media::CameraAvailability::kAvailable);
}
} // namespace
TEST(MediaDevicesUtilTest, TranslateEmptyMediaDeviceInfoArray) {
MediaDeviceSaltAndOrigin salt_and_origin = ExampleSaltAndOrigin();
blink::WebMediaDeviceInfoArray web_media_device_infos =
TranslateMediaDeviceInfoArray(/*has_permission=*/false, salt_and_origin,
{});
EXPECT_TRUE(web_media_device_infos.empty());
web_media_device_infos = TranslateMediaDeviceInfoArray(
/*has_permission=*/true, salt_and_origin, {});
EXPECT_TRUE(web_media_device_infos.empty());
}
TEST(MediaDevicesUtilBrowserTest, TranslateMediaDeviceInfoWithPermission) {
MediaDeviceSaltAndOrigin salt_and_origin = ExampleSaltAndOrigin();
blink::WebMediaDeviceInfo original_info = ExampleWebMediaDeviceInfo();
blink::WebMediaDeviceInfo translated_info = TranslateMediaDeviceInfo(
/*has_permission=*/true, salt_and_origin, original_info);
EXPECT_EQ(
translated_info.device_id,
GetHMACForRawMediaDeviceID(salt_and_origin, original_info.device_id));
EXPECT_EQ(translated_info.label, original_info.label);
EXPECT_EQ(translated_info.group_id,
GetHMACForRawMediaDeviceID(salt_and_origin, original_info.group_id,
/*use_group_salt=*/true));
EXPECT_EQ(translated_info.video_facing, original_info.video_facing);
EXPECT_EQ(translated_info.video_control_support.pan,
original_info.video_control_support.pan);
EXPECT_EQ(translated_info.video_control_support.tilt,
original_info.video_control_support.tilt);
EXPECT_EQ(translated_info.video_control_support.zoom,
original_info.video_control_support.zoom);
EXPECT_EQ(translated_info.availability, original_info.availability);
}
TEST(MediaDevicesUtilBrowserTest, TranslateMediaDeviceInfoWithoutPermission) {
MediaDeviceSaltAndOrigin salt_and_origin = ExampleSaltAndOrigin();
blink::WebMediaDeviceInfo original_info = ExampleWebMediaDeviceInfo();
blink::WebMediaDeviceInfo translated_info = TranslateMediaDeviceInfo(
/*has_permission=*/false, salt_and_origin, original_info);
EXPECT_TRUE(translated_info.device_id.empty());
EXPECT_TRUE(translated_info.label.empty());
EXPECT_TRUE(translated_info.group_id.empty());
EXPECT_EQ(translated_info.video_facing, blink::mojom::FacingMode::kNone);
EXPECT_FALSE(translated_info.video_control_support.pan);
EXPECT_FALSE(translated_info.video_control_support.tilt);
EXPECT_FALSE(translated_info.video_control_support.zoom);
EXPECT_FALSE(translated_info.availability.has_value());
}
TEST(MediaDevicesUtilTest, TranslateSpecialDeviceIDs) {
MediaDeviceSaltAndOrigin salt_and_origin = ExampleSaltAndOrigin();
const std::string raw_default_id(
media::AudioDeviceDescription::kDefaultDeviceId);
const std::string hashed_default_id =
GetHMACForRawMediaDeviceID(salt_and_origin, raw_default_id);
EXPECT_TRUE(DoesRawMediaDeviceIDMatchHMAC(salt_and_origin, hashed_default_id,
raw_default_id));
EXPECT_EQ(raw_default_id, hashed_default_id);
const std::string raw_communications_id(
media::AudioDeviceDescription::kCommunicationsDeviceId);
const std::string hashed_communications_id =
GetHMACForRawMediaDeviceID(salt_and_origin, raw_communications_id);
EXPECT_TRUE(DoesRawMediaDeviceIDMatchHMAC(
salt_and_origin, hashed_communications_id, raw_communications_id));
EXPECT_EQ(raw_communications_id, hashed_communications_id);
const std::string raw_empty_id;
const std::string hashed_empty_id =
GetHMACForRawMediaDeviceID(salt_and_origin, raw_empty_id);
EXPECT_TRUE(DoesRawMediaDeviceIDMatchHMAC(salt_and_origin, hashed_empty_id,
raw_empty_id));
EXPECT_EQ(raw_empty_id, hashed_empty_id);
}
TEST(MediaDevicesUtilTest, TranslateNonSpecialDeviceID) {
MediaDeviceSaltAndOrigin salt_and_origin = ExampleSaltAndOrigin();
const std::string raw_other_id("other-unique-id");
const std::string hashed_other_id =
GetHMACForRawMediaDeviceID(salt_and_origin, raw_other_id);
EXPECT_TRUE(DoesRawMediaDeviceIDMatchHMAC(salt_and_origin, hashed_other_id,
raw_other_id));
EXPECT_FALSE(DoesRawMediaDeviceIDMatchHMAC(
salt_and_origin, hashed_other_id,
media::AudioDeviceDescription::kDefaultDeviceId));
EXPECT_FALSE(DoesRawMediaDeviceIDMatchHMAC(
salt_and_origin, hashed_other_id,
media::AudioDeviceDescription::kCommunicationsDeviceId));
EXPECT_NE(raw_other_id, hashed_other_id);
EXPECT_EQ(hashed_other_id.size(), 64U);
for (const char& c : hashed_other_id) {
EXPECT_TRUE(base::IsAsciiDigit(c) || (c >= 'a' && c <= 'f'));
}
}
} // namespace content