| Index: chrome/browser/permissions/permission_request_manager_browsertest.cc
|
| diff --git a/chrome/browser/permissions/permission_request_manager_browsertest.cc b/chrome/browser/permissions/permission_request_manager_browsertest.cc
|
| index 4e74b17f0c82e50a922c8d12905b4247d0ff6f01..3d4f52deaafc0d6229936ec274fbc0712c7d596c 100644
|
| --- a/chrome/browser/permissions/permission_request_manager_browsertest.cc
|
| +++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc
|
| @@ -7,10 +7,17 @@
|
| #include "base/command_line.h"
|
| #include "base/metrics/field_trial.h"
|
| #include "build/build_config.h"
|
| +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
|
| +#include "chrome/browser/custom_handlers/register_protocol_handler_permission_request.h"
|
| +#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
|
| +#include "chrome/browser/media/webrtc/media_stream_devices_controller.h"
|
| #include "chrome/browser/permissions/permission_context_base.h"
|
| +#include "chrome/browser/permissions/permission_request_impl.h"
|
| #include "chrome/browser/permissions/permission_util.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| +#include "chrome/browser/ui/test/test_browser_dialog.h"
|
| #include "chrome/browser/ui/website_settings/mock_permission_prompt_factory.h"
|
| #include "chrome/test/base/in_process_browser_test.h"
|
| #include "chrome/test/base/ui_test_utils.h"
|
| @@ -20,6 +27,39 @@
|
| #include "content/public/test/test_utils.h"
|
| #include "net/test/embedded_test_server/embedded_test_server.h"
|
|
|
| +namespace test {
|
| +class MediaStreamDevicesControllerTestApi
|
| + : public MediaStreamDevicesController::PermissionPromptDelegate {
|
| + public:
|
| + static void AddRequestToManager(
|
| + PermissionRequestManager* manager,
|
| + content::WebContents* web_contents,
|
| + const content::MediaStreamRequest& request,
|
| + const content::MediaResponseCallback& callback) {
|
| + MediaStreamDevicesControllerTestApi delegate(manager);
|
| + MediaStreamDevicesController::RequestPermissionsWithDelegate(
|
| + web_contents, request, callback, &delegate);
|
| + }
|
| +
|
| + private:
|
| + // MediaStreamDevicesController::PermissionPromptDelegate:
|
| + void ShowPrompt(
|
| + bool user_gesture,
|
| + content::WebContents* web_contents,
|
| + std::unique_ptr<MediaStreamDevicesController> controller) override {
|
| + manager_->AddRequest(controller.release());
|
| + }
|
| +
|
| + explicit MediaStreamDevicesControllerTestApi(
|
| + PermissionRequestManager* manager)
|
| + : manager_(manager) {}
|
| +
|
| + PermissionRequestManager* manager_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MediaStreamDevicesControllerTestApi);
|
| +};
|
| +} // namespace test
|
| +
|
| namespace {
|
|
|
| const char* kPermissionsKillSwitchFieldStudy =
|
| @@ -68,8 +108,166 @@ class PermissionRequestManagerBrowserTest : public InProcessBrowserTest {
|
|
|
| private:
|
| std::unique_ptr<MockPermissionPromptFactory> mock_permission_prompt_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PermissionRequestManagerBrowserTest);
|
| };
|
|
|
| +// Harness for testing permissions dialogs invoked by PermissionRequestManager.
|
| +// Uses a "real" PermissionPromptFactory rather than a mock.
|
| +class PermissionDialogTest
|
| + : public SupportsTestDialog<PermissionRequestManagerBrowserTest> {
|
| + public:
|
| + PermissionDialogTest() {}
|
| +
|
| + // InProcessBrowserTest:
|
| + void SetUpOnMainThread() override {
|
| + // Skip super: It will install a mock permission UI factory, but for this
|
| + // test we want to show "real" UI.
|
| + InProcessBrowserTest::SetUpOnMainThread();
|
| + }
|
| +
|
| + private:
|
| + GURL GetUrl() { return GURL("https://example.com"); }
|
| +
|
| + PermissionRequest* MakeRegisterProtocolHandlerRequest();
|
| + void AddMediaRequest(PermissionRequestManager* manager,
|
| + ContentSettingsType permission);
|
| + PermissionRequest* MakePermissionRequest(ContentSettingsType permission);
|
| +
|
| + // TestBrowserDialog:
|
| + void ShowDialog(const std::string& name) override;
|
| +
|
| + // Holds requests that do not delete themselves.
|
| + std::vector<std::unique_ptr<PermissionRequest>> owned_requests_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PermissionDialogTest);
|
| +};
|
| +
|
| +PermissionRequest* PermissionDialogTest::MakeRegisterProtocolHandlerRequest() {
|
| + std::string protocol = "mailto";
|
| + bool user_gesture = true;
|
| + ProtocolHandler handler =
|
| + ProtocolHandler::CreateProtocolHandler(protocol, GetUrl());
|
| + ProtocolHandlerRegistry* registry =
|
| + ProtocolHandlerRegistryFactory::GetForBrowserContext(
|
| + browser()->profile());
|
| + // Deleted in RegisterProtocolHandlerPermissionRequest::RequestFinished().
|
| + return new RegisterProtocolHandlerPermissionRequest(registry, handler,
|
| + GetUrl(), user_gesture);
|
| +}
|
| +
|
| +void PermissionDialogTest::AddMediaRequest(PermissionRequestManager* manager,
|
| + ContentSettingsType permission) {
|
| + content::WebContents* web_contents =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| + content::MediaStreamRequestType request_type = content::MEDIA_DEVICE_ACCESS;
|
| + content::MediaStreamType audio_type = content::MEDIA_NO_SERVICE;
|
| + content::MediaStreamType video_type = content::MEDIA_NO_SERVICE;
|
| + std::string audio_id = "audio_id";
|
| + std::string video_id = "video_id";
|
| +
|
| + if (permission == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)
|
| + audio_type = content::MEDIA_DEVICE_AUDIO_CAPTURE;
|
| + else
|
| + video_type = content::MEDIA_DEVICE_VIDEO_CAPTURE;
|
| + content::MediaStreamRequest request(0, 0, 0, GetUrl(), false, request_type,
|
| + audio_id, video_id, audio_type,
|
| + video_type, false);
|
| +
|
| + // Add fake devices, otherwise the request will auto-block.
|
| + MediaCaptureDevicesDispatcher::GetInstance()->SetTestAudioCaptureDevices(
|
| + content::MediaStreamDevices(
|
| + 1, content::MediaStreamDevice(content::MEDIA_DEVICE_AUDIO_CAPTURE,
|
| + audio_id, "Fake Audio")));
|
| + MediaCaptureDevicesDispatcher::GetInstance()->SetTestVideoCaptureDevices(
|
| + content::MediaStreamDevices(
|
| + 1, content::MediaStreamDevice(content::MEDIA_DEVICE_VIDEO_CAPTURE,
|
| + video_id, "Fake Video")));
|
| +
|
| + auto response = [](const content::MediaStreamDevices& devices,
|
| + content::MediaStreamRequestResult result,
|
| + std::unique_ptr<content::MediaStreamUI> ui) {};
|
| + test::MediaStreamDevicesControllerTestApi::AddRequestToManager(
|
| + manager, web_contents, request, base::Bind(response));
|
| +}
|
| +
|
| +PermissionRequest* PermissionDialogTest::MakePermissionRequest(
|
| + ContentSettingsType permission) {
|
| + bool user_gesture = true;
|
| + auto decided = [](bool, ContentSetting) {};
|
| + auto cleanup = [] {}; // Leave cleanup to test harness destructor.
|
| + owned_requests_.push_back(base::MakeUnique<PermissionRequestImpl>(
|
| + GetUrl(), permission, browser()->profile(), user_gesture,
|
| + base::Bind(decided), base::Bind(cleanup)));
|
| + return owned_requests_.back().get();
|
| +}
|
| +
|
| +void PermissionDialogTest::ShowDialog(const std::string& name) {
|
| + constexpr const char* kMultipleName = "multiple";
|
| + // Permissions to request for a "multiple" request. Only types handled in
|
| + // PermissionRequestImpl::GetMessageTextFragment() are valid.
|
| + constexpr ContentSettingsType kMultipleRequests[] = {
|
| + CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| + CONTENT_SETTINGS_TYPE_MIDI_SYSEX};
|
| + constexpr struct {
|
| + const char* name;
|
| + ContentSettingsType type;
|
| + } kNameToType[] = {
|
| + {"flash", CONTENT_SETTINGS_TYPE_PLUGINS},
|
| + {"geolocation", CONTENT_SETTINGS_TYPE_GEOLOCATION},
|
| + {"protected_media", CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER},
|
| + {"notifications", CONTENT_SETTINGS_TYPE_NOTIFICATIONS},
|
| + {"mic", CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC},
|
| + {"camera", CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA},
|
| + {"protocol_handlers", CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS},
|
| + {"midi", CONTENT_SETTINGS_TYPE_MIDI_SYSEX},
|
| + {kMultipleName, CONTENT_SETTINGS_TYPE_DEFAULT}};
|
| + const auto* it = std::begin(kNameToType);
|
| + for (; it != std::end(kNameToType); ++it) {
|
| + if (name == it->name)
|
| + break;
|
| + }
|
| + if (it == std::end(kNameToType)) {
|
| + ADD_FAILURE() << "Unknown: " << name;
|
| + return;
|
| + }
|
| + PermissionRequestManager* manager = GetPermissionRequestManager();
|
| + switch (it->type) {
|
| + case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS:
|
| + manager->AddRequest(MakeRegisterProtocolHandlerRequest());
|
| + break;
|
| + case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
|
| + // TODO(tapted): Prompt for downloading multiple files.
|
| + break;
|
| + case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE:
|
| + // TODO(tapted): Prompt for quota request.
|
| + break;
|
| + case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
|
| + case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
|
| + AddMediaRequest(manager, it->type);
|
| + break;
|
| + // Regular permissions requests.
|
| + case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
|
| + case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING: // Same as notifications.
|
| + case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
|
| + case CONTENT_SETTINGS_TYPE_GEOLOCATION:
|
| + case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: // ChromeOS only.
|
| + case CONTENT_SETTINGS_TYPE_PPAPI_BROKER:
|
| + case CONTENT_SETTINGS_TYPE_PLUGINS: // Flash.
|
| + manager->AddRequest(MakePermissionRequest(it->type));
|
| + break;
|
| + case CONTENT_SETTINGS_TYPE_DEFAULT:
|
| + EXPECT_EQ(kMultipleName, name);
|
| + for (auto request : kMultipleRequests)
|
| + manager->AddRequest(MakePermissionRequest(request));
|
| + break;
|
| + default:
|
| + ADD_FAILURE() << "Not a permission type, or one that doesn't prompt.";
|
| + return;
|
| + }
|
| + manager->DisplayPendingRequests();
|
| +}
|
| +
|
| // Requests before the load event should be bundled into one bubble.
|
| // http://crbug.com/512849 flaky
|
| IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest,
|
| @@ -248,4 +446,55 @@ IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest,
|
| EXPECT_EQ(1, bubble_factory()->total_request_count());
|
| }
|
|
|
| +// Host wants to run flash.
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_flash) {
|
| + RunDialog();
|
| +}
|
| +
|
| +// Host wants to know your location.
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_geolocation) {
|
| + RunDialog();
|
| +}
|
| +
|
| +// Host wants to show notifications.
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_notifications) {
|
| + RunDialog();
|
| +}
|
| +
|
| +// Host wants to use your microphone.
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_mic) {
|
| + RunDialog();
|
| +}
|
| +
|
| +// Host wants to use your camera.
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_camera) {
|
| + RunDialog();
|
| +}
|
| +
|
| +// Host wants to open email links.
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_protocol_handlers) {
|
| + RunDialog();
|
| +}
|
| +
|
| +// Host wants to use your MIDI devices.
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_midi) {
|
| + RunDialog();
|
| +}
|
| +
|
| +// Shows a permissions bubble with multiple requests.
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_multiple) {
|
| + RunDialog();
|
| +}
|
| +
|
| +// CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER is ChromeOS only.
|
| +#if defined(OS_CHROMEOS)
|
| +#define MAYBE_InvokeDialog_protected_media InvokeDialog_protected_media
|
| +#else
|
| +#define MAYBE_InvokeDialog_protected_media DISABLED_InvokeDialog_protected_media
|
| +#endif
|
| +IN_PROC_BROWSER_TEST_F(PermissionDialogTest,
|
| + MAYBE_InvokeDialog_protected_media) {
|
| + RunDialog();
|
| +}
|
| +
|
| } // anonymous namespace
|
|
|