Commit 191c0485 authored by Guido Urdaneta's avatar Guido Urdaneta Committed by Commit Bot

[MediaDevices] Add async version of GetMediaDeviceIDForHMAC.

This version intends to replace the sync version, which suffers from
several issues.
It is going to be used by crrev.com/c/1424680

Bug: 648155
Change-Id: I4ede55a02a2930ed854263c47bceb37bcdf57f28
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1532223
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarMarina Ciocea <marinaciocea@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#642737}
parent 322fc0ed
......@@ -263,6 +263,28 @@ MediaStreamDevices DisplayMediaDevicesFromFakeDeviceConfig(bool request_audio) {
return devices;
}
void FinalizeGetMediaDeviceIDForHMAC(
blink::MediaDeviceType type,
const std::string& salt,
const url::Origin& security_origin,
const std::string& source_id,
scoped_refptr<base::SequencedTaskRunner> task_runner,
base::OnceCallback<void(const base::Optional<std::string>&)> callback,
const MediaDeviceEnumeration& enumeration) {
DCHECK(type == blink::MEDIA_DEVICE_TYPE_AUDIO_INPUT ||
type == blink::MEDIA_DEVICE_TYPE_VIDEO_INPUT);
for (const auto& device : enumeration[type]) {
if (MediaStreamManager::DoesMediaDeviceIDMatchHMAC(
salt, security_origin, source_id, device.device_id)) {
task_runner->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), device.device_id));
return;
}
}
task_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(callback), base::nullopt));
}
} // namespace
// MediaStreamManager::DeviceRequest represents a request to either enumerate
......@@ -2122,6 +2144,29 @@ bool MediaStreamManager::DoesMediaDeviceIDMatchHMAC(
return guid_from_raw_device_id == device_guid;
}
// static
void MediaStreamManager::GetMediaDeviceIDForHMAC(
blink::MediaStreamType stream_type,
std::string salt,
url::Origin security_origin,
std::string hmac_device_id,
scoped_refptr<base::SequencedTaskRunner> task_runner,
base::OnceCallback<void(const base::Optional<std::string>&)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(stream_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE ||
stream_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE);
MediaStreamManager* msm = g_media_stream_manager_tls_ptr.Pointer()->Get();
blink::MediaDeviceType device_type = ConvertToMediaDeviceType(stream_type);
MediaDevicesManager::BoolDeviceTypes requested_types;
requested_types[device_type] = true;
msm->media_devices_manager()->EnumerateDevices(
requested_types,
base::BindOnce(&FinalizeGetMediaDeviceIDForHMAC, device_type,
std::move(salt), std::move(security_origin),
std::move(hmac_device_id), std::move(task_runner),
std::move(callback)));
}
// static
bool MediaStreamManager::IsOriginAllowed(int render_process_id,
const url::Origin& origin) {
......
......@@ -300,6 +300,18 @@ class CONTENT_EXPORT MediaStreamManager
const std::string& device_guid,
const std::string& raw_unique_id);
// Convenience method to get the raw device ID from the HMAC |hmac_device_id|
// for the given |security_origin| and |salt|. |stream_type| must be
// blink::MEDIA_DEVICE_AUDIO_CAPTURE or blink::MEDIA_DEVICE_VIDEO_CAPTURE.
// The result will be returned via |callback| on the given |task_runner|.
static void GetMediaDeviceIDForHMAC(
blink::MediaStreamType stream_type,
std::string salt,
url::Origin security_origin,
std::string hmac_device_id,
scoped_refptr<base::SequencedTaskRunner> task_runner,
base::OnceCallback<void(const base::Optional<std::string>&)> callback);
// Returns true if the renderer process identified with |render_process_id|
// is allowed to access |origin|.
static bool IsOriginAllowed(int render_process_id, const url::Origin& origin);
......
......@@ -65,6 +65,7 @@ typedef media::FakeAudioManager AudioManagerPlatform;
namespace {
const char kMockSalt[] = "";
const char kFakeDeviceIdPrefix[] = "fake_device_id_";
// This class mocks the audio manager and overrides some methods to ensure that
// we can run our tests on the buildbots.
......@@ -88,7 +89,7 @@ class MockAudioManager : public AudioManagerPlatform {
for (size_t i = 0; i < num_input_devices_; i++) {
device_names->push_back(media::AudioDeviceName(
std::string("fake_device_name_") + base::NumberToString(i),
std::string("fake_device_id_") + base::NumberToString(i)));
std::string(kFakeDeviceIdPrefix) + base::NumberToString(i)));
}
}
......@@ -103,7 +104,7 @@ class MockAudioManager : public AudioManagerPlatform {
for (size_t i = 0; i < num_output_devices_; i++) {
device_names->push_back(media::AudioDeviceName(
std::string("fake_device_name_") + base::NumberToString(i),
std::string("fake_device_id_") + base::NumberToString(i)));
std::string(kFakeDeviceIdPrefix) + base::NumberToString(i)));
}
}
......@@ -687,4 +688,35 @@ TEST_F(MediaStreamManagerTest, DesktopCaptureDeviceChanged) {
video_device.session_id);
}
TEST_F(MediaStreamManagerTest, GetMediaDeviceIDForHMAC) {
const char kSalt[] = "my salt";
const url::Origin kOrigin = url::Origin::Create(GURL("http://example.com"));
const std::string kExistingRawDeviceId =
std::string(kFakeDeviceIdPrefix) + "0";
const std::string kExistingHmacDeviceId =
MediaStreamManager::GetHMACForMediaDeviceID(kSalt, kOrigin,
kExistingRawDeviceId);
MediaStreamManager::GetMediaDeviceIDForHMAC(
blink::MEDIA_DEVICE_AUDIO_CAPTURE, kSalt, kOrigin, kExistingHmacDeviceId,
base::SequencedTaskRunnerHandle::Get(),
base::BindOnce(
[](const std::string& expected_raw_device_id,
const base::Optional<std::string>& raw_device_id) {
ASSERT_TRUE(raw_device_id.has_value());
EXPECT_EQ(*raw_device_id, expected_raw_device_id);
},
kExistingRawDeviceId));
base::RunLoop().RunUntilIdle();
const std::string kNonexistingHmacDeviceId = "does not exist";
MediaStreamManager::GetMediaDeviceIDForHMAC(
blink::MEDIA_DEVICE_AUDIO_CAPTURE, kSalt, kOrigin,
kNonexistingHmacDeviceId, base::SequencedTaskRunnerHandle::Get(),
base::BindOnce([](const base::Optional<std::string>& raw_device_id) {
EXPECT_FALSE(raw_device_id.has_value());
}));
base::RunLoop().RunUntilIdle();
}
} // namespace content
......@@ -4,6 +4,7 @@
#include "content/public/browser/media_device_id.h"
#include "base/strings/string_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "media/audio/audio_device_description.h"
......@@ -38,6 +39,18 @@ bool GetMediaDeviceIDForHMAC(blink::MediaStreamType stream_type,
device_id);
}
void GetMediaDeviceIDForHMAC(
blink::MediaStreamType stream_type,
std::string salt,
url::Origin security_origin,
std::string hmac_device_id,
base::OnceCallback<void(const base::Optional<std::string>&)> callback) {
MediaStreamManager::GetMediaDeviceIDForHMAC(
stream_type, std::move(salt), std::move(security_origin),
std::move(hmac_device_id), base::SequencedTaskRunnerHandle::Get(),
std::move(callback));
}
bool IsValidDeviceId(const std::string& device_id) {
constexpr int hash_size = 64; // 32 bytes * 2 char/byte hex encoding
if (media::AudioDeviceDescription::IsDefaultDevice(device_id) ||
......
......@@ -34,12 +34,24 @@ CONTENT_EXPORT bool DoesMediaDeviceIDMatchHMAC(
const std::string& device_guid,
const std::string& raw_unique_id);
// This function is deprecated. Use the callback version below instead.
CONTENT_EXPORT bool GetMediaDeviceIDForHMAC(blink::MediaStreamType stream_type,
const std::string& salt,
const url::Origin& security_origin,
const std::string& source_id,
std::string* device_id);
// Returns the raw device ID for the given HMAC |hmac_device_id| for the given
// |security_origin| and |salt|. The result is passed via |callback| on the
// task runner where this function is called. If |hmac_device_id| is not a
// valid device ID nullopt is returned.
CONTENT_EXPORT void GetMediaDeviceIDForHMAC(
blink::MediaStreamType stream_type,
std::string salt,
url::Origin security_origin,
std::string hmac_device_id,
base::OnceCallback<void(const base::Optional<std::string>&)> callback);
CONTENT_EXPORT bool IsValidDeviceId(const std::string& device_id);
} // namespace content
......
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