[go: nahoru, domu]

blob: 303b80ac827e86bc2b4cd6f52fc4f7c3dbcd11ff [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/webrtc/media_stream_devices_controller.h"
#include "base/test/bind.h"
#include "base/test/test_future.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/mock_permission_controller.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_web_contents_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#if BUILDFLAG(IS_ANDROID)
#include "content/public/browser/render_widget_host_view.h"
#include "ui/android/window_android.h"
#endif
using testing::_;
namespace {
blink::MediaStreamDevices CreateFakeDevices(
blink::mojom::MediaStreamType type) {
blink::MediaStreamDevices devices;
devices.reserve(3);
for (size_t i = 0; i < devices.capacity(); ++i) {
devices.emplace_back(type, "id_" + base::NumberToString(i),
"name " + base::NumberToString(i));
}
return devices;
}
class FakeEnumerator : public webrtc::MediaStreamDeviceEnumeratorImpl {
public:
FakeEnumerator()
: audio_capture_devices_(CreateFakeDevices(
blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE)),
video_capture_devices_(CreateFakeDevices(
blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE)) {}
const blink::MediaStreamDevices& GetAudioCaptureDevices() const override {
return audio_capture_devices_;
}
const blink::MediaStreamDevices& GetVideoCaptureDevices() const override {
return video_capture_devices_;
}
private:
const blink::MediaStreamDevices audio_capture_devices_;
const blink::MediaStreamDevices video_capture_devices_;
};
class MockPermissionController : public content::MockPermissionController {
public:
MOCK_METHOD(
void,
RequestPermissionsFromCurrentDocument,
(content::RenderFrameHost * render_frame_host,
content::PermissionRequestDescription request_description,
base::OnceCallback<
void(const std::vector<blink::mojom::PermissionStatus>&)> callback));
};
} // namespace
class MediaStreamDevicesControllerTest : public testing::Test {
void SetUp() override { InitializeWebContents(); }
void InitializeWebContents() {
browser_context_.SetPermissionControllerForTesting(
std::make_unique<MockPermissionController>());
web_contents_ =
test_web_contents_factory_.CreateWebContents(&browser_context_);
render_frame_host_ = web_contents_->GetPrimaryMainFrame();
render_frame_host_id_ = render_frame_host_->GetGlobalId();
content::OverrideLastCommittedOrigin(render_frame_host_, origin_);
#if BUILDFLAG(IS_ANDROID)
// Create a scoped window so that
// WebContents::GetNativeView()->GetWindowAndroid() does not return
// null.
window_ = ui::WindowAndroid::CreateForTesting();
window_.get()->get()->AddChild(web_contents_->GetNativeView());
web_contents_->GetRenderWidgetHostView()->Show();
#endif
}
protected:
content::BrowserTaskEnvironment task_environment_;
FakeEnumerator enumerator_;
content::TestBrowserContext browser_context_;
content::TestWebContentsFactory test_web_contents_factory_;
raw_ptr<content::WebContents> web_contents_;
raw_ptr<content::RenderFrameHost> render_frame_host_;
content::GlobalRenderFrameHostId render_frame_host_id_;
const url::Origin origin_ = url::Origin::Create(GURL{"https://stuff.com"});
#if BUILDFLAG(IS_ANDROID)
std::unique_ptr<ui::WindowAndroid::ScopedWindowAndroidForTesting> window_;
#endif
};
TEST_F(MediaStreamDevicesControllerTest, RequestPermissions) {
auto* mock_permission_controller = static_cast<MockPermissionController*>(
browser_context_.GetPermissionController());
ON_CALL(*mock_permission_controller, GetPermissionResultForCurrentDocument)
.WillByDefault([](blink::PermissionType permission,
content::RenderFrameHost* render_frame_host) {
return content::PermissionResult{
content::PermissionStatus::GRANTED,
content::PermissionStatusSource::UNSPECIFIED,
};
});
const auto kRequestedAudioCaptureDevice =
enumerator_.GetAudioCaptureDevices().back();
const auto kRequestedVideoCaptureDevice =
enumerator_.GetVideoCaptureDevices().back();
content::PermissionRequestDescription expected_description{
{blink::PermissionType::AUDIO_CAPTURE,
blink::PermissionType::VIDEO_CAPTURE},
false};
expected_description.requested_audio_capture_device_ids = {
kRequestedAudioCaptureDevice.id};
expected_description.requested_video_capture_device_ids = {
kRequestedVideoCaptureDevice.id};
EXPECT_CALL(*mock_permission_controller,
RequestPermissionsFromCurrentDocument(render_frame_host_.get(),
expected_description, _))
.WillOnce(
[](auto*, auto,
base::OnceCallback<void(
const std::vector<content::PermissionStatus>&)> callback) {
std::move(callback).Run({content::PermissionStatus::GRANTED,
content::PermissionStatus::GRANTED});
});
blink::MediaStreamDevice returned_audio_capture_device;
blink::MediaStreamDevice returned_video_capture_device;
base::test::TestFuture<blink::mojom::MediaStreamRequestResult,
blink::mojom::StreamDevicesPtr>
result_future;
webrtc::MediaStreamDevicesController::RequestPermissions(
content::MediaStreamRequest{
/*render_process_id=*/render_frame_host_id_.child_id,
/*render_frame_id=*/render_frame_host_id_.frame_routing_id,
/*page_request_id=*/0, /*url_origin=*/origin_, /*user_gesture=*/false,
/*request_type=*/
blink::MediaStreamRequestType::MEDIA_GENERATE_STREAM,
/*requested_audio_device_ids=*/{kRequestedAudioCaptureDevice.id},
/*requested_video_device_ids=*/{kRequestedVideoCaptureDevice.id},
blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE,
blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE,
/*disable_local_echo=*/false,
/*request_pan_tilt_zoom_permission=*/false},
&enumerator_,
base::BindLambdaForTesting(
[&](const blink::mojom::StreamDevicesSet& stream_devices_set,
blink::mojom::MediaStreamRequestResult result,
bool blocked_by_permissions_policy, ContentSetting audio_setting,
ContentSetting video_setting) {
CHECK_EQ(stream_devices_set.stream_devices.size(), 1u);
result_future.SetValue(
result, stream_devices_set.stream_devices[0]->Clone());
}));
auto [result, stream_devices] = result_future.Take();
ASSERT_EQ(result, blink::mojom::MediaStreamRequestResult::OK);
ASSERT_TRUE(stream_devices->audio_device.has_value());
EXPECT_TRUE(
stream_devices->audio_device->IsSameDevice(kRequestedAudioCaptureDevice));
ASSERT_TRUE(stream_devices->video_device.has_value());
EXPECT_TRUE(
stream_devices->video_device->IsSameDevice(kRequestedVideoCaptureDevice));
}