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 2cbfc796ba7e0a62e21dfbadd75deb17d74ef714..ddc4c25acea21f7089b8a90b68f64cb21ee77f66 100644 |
--- a/chrome/browser/permissions/permission_request_manager_browsertest.cc |
+++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc |
@@ -7,10 +7,16 @@ |
#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/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 +26,8 @@ |
#include "content/public/test/test_utils.h" |
#include "net/test/embedded_test_server/embedded_test_server.h" |
+using content::PermissionType; |
+ |
namespace { |
const char* kPermissionsKillSwitchFieldStudy = |
@@ -55,7 +63,7 @@ class PermissionRequestManagerBrowserTest : public InProcessBrowserTest { |
return mock_permission_prompt_factory_.get(); |
} |
- void EnableKillSwitch(content::PermissionType permission_type) { |
+ void EnableKillSwitch(PermissionType permission_type) { |
std::map<std::string, std::string> params; |
params[PermissionUtil::GetPermissionString(permission_type)] = |
kPermissionsKillSwitchBlockedValue; |
@@ -68,8 +76,169 @@ 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: |
+ // Values for dialog styles that are not a content::PermissionType. |
+ enum CustomPermissionTypes { |
+ REGISTER_PROTOCOL_HANDLER = 0, |
+ MULTIPLE_REQUESTS = static_cast<int>(PermissionType::NUM), |
+ |
+ // TODO(tapted): Implement these: |
+ DOWNLOAD_MULTIPLE_FILES, |
+ QUOTA_REQUEST, |
+ }; |
+ |
+ PermissionDialogTest() {} |
+ |
+ // InProcessBrowserTest: |
+ void SetUpOnMainThread() override { |
+ InProcessBrowserTest::SetUpOnMainThread(); // Skip super. |
+ } |
+ |
+ static std::vector<std::string> NameProvider() { |
+ // Put RegisterProtocolHandler at index 0. There is no PermissionType with |
+ // value 0, and no PermissionType for RPH, even though there is a request |
+ // class for it. ShowDialog is called with index 0 when no dialog is chosen. |
+ std::vector<std::string> names = {"RegisterProtocolHandler"}; |
+ auto add = [&names](PermissionType type, const std::string& name) { |
+ EXPECT_EQ(names.size(), static_cast<size_t>(type)); |
+ names.push_back(name); |
+ }; |
+ add(PermissionType::MIDI_SYSEX, "MidiSysex"); |
+ |
+ // Note: The next 2 look kinda the same. |
+ add(PermissionType::PUSH_MESSAGING, "PushMessaging"); |
+ add(PermissionType::NOTIFICATIONS, "Notifications"); |
+ |
+ add(PermissionType::GEOLOCATION, "Geolocation"); |
+ |
+#if defined(OS_CHROMEOS) |
+ // ProtectedMedia is ChromeOS only (fails with no icon otherwise). |
+ add(PermissionType::PROTECTED_MEDIA_IDENTIFIER, "ProtectedMedia"); |
+#else |
+ add(PermissionType::PROTECTED_MEDIA_IDENTIFIER, "DISABLED_ProtectedMedia"); |
+#endif |
+ |
+ // Note: This fails because there is no icon. |
+ add(PermissionType::MIDI, "DISABLED_Midi"); |
+ |
+ // Note: Doesn't prompt. See durable_storage_permission_context.cc. |
+ add(PermissionType::DURABLE_STORAGE, "DISABLED_DurableStorage"); |
+ |
+ add(PermissionType::AUDIO_CAPTURE, "AudioCapture"); |
+ add(PermissionType::VIDEO_CAPTURE, "VideoCapture"); |
+ |
+ // Note: Doesn't prompt. See background_sync_manager.cc. |
+ add(PermissionType::BACKGROUND_SYNC, "DISABLED_BackgroundSync"); |
+ |
+ add(PermissionType::FLASH, "Flash"); |
+ static_assert(static_cast<int>(PermissionType::NUM) == 12, |
+ "PermissionType count changed. Please update dialog tests."); |
+ |
+ EXPECT_EQ(names.size(), MULTIPLE_REQUESTS); |
+ names.push_back("MultipleRequests"); |
+ return names; |
+ } |
+ |
+ GURL GetUrl() { return GURL("https://example.com"); } |
+ |
+ PermissionRequest* 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); |
+ } |
+ |
+ PermissionRequest* MakeMediaRequest(PermissionType 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 == PermissionType::AUDIO_CAPTURE) |
+ 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) {}; |
+ // Deleted in MediaStreamDevicesController::RequestFinished(). |
+ return new MediaStreamDevicesController(web_contents, request, |
+ base::Bind(response)); |
+ } |
+ |
+ PermissionRequest* MakeRequest(PermissionType permission) { |
+ if (permission == PermissionType::AUDIO_CAPTURE || |
+ permission == PermissionType::VIDEO_CAPTURE) |
+ return MakeMediaRequest(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(); |
+ } |
+ |
+ // TestDialogInterface: |
+ void ShowDialog(int index) override { |
+ PermissionRequestManager* manager = GetPermissionRequestManager(); |
+ if (index == REGISTER_PROTOCOL_HANDLER) { |
+ manager->AddRequest(MakeRegisterProtocolHandlerRequest()); |
+ } else if (index < static_cast<int>(PermissionType::NUM)) { |
+ PermissionType permission = static_cast<PermissionType>(index); |
+ manager->AddRequest(MakeRequest(permission)); |
+ } else if (index == MULTIPLE_REQUESTS) { |
+ // Only types handled in PermissionRequestImpl::GetMessageTextFragment() |
+ // can be combined this way. |
+ manager->AddRequest(MakeRequest(PermissionType::GEOLOCATION)); |
+ manager->AddRequest(MakeRequest(PermissionType::NOTIFICATIONS)); |
+ manager->AddRequest(MakeRequest(PermissionType::MIDI_SYSEX)); |
+ } else { |
+ NOTREACHED(); |
+ } |
+ manager->DisplayPendingRequests(); |
+ } |
+ |
+ private: |
+ std::vector<std::unique_ptr<PermissionRequest>> owned_requests_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PermissionDialogTest); |
}; |
+TEST_BROWSER_DIALOG(PermissionDialogTest); |
+ |
// Requests before the load event should be bundled into one bubble. |
// http://crbug.com/512849 flaky |
IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest, |
@@ -192,7 +361,7 @@ IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest, |
embedded_test_server()->GetURL("/permissions/killswitch_tester.html")); |
// Now enable the geolocation killswitch. |
- EnableKillSwitch(content::PermissionType::GEOLOCATION); |
+ EnableKillSwitch(PermissionType::GEOLOCATION); |
content::WebContents* web_contents = |
browser()->tab_strip_model()->GetActiveWebContents(); |
@@ -228,7 +397,7 @@ IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest, |
embedded_test_server()->GetURL("/permissions/killswitch_tester.html")); |
// Now enable the notifications killswitch. |
- EnableKillSwitch(content::PermissionType::NOTIFICATIONS); |
+ EnableKillSwitch(PermissionType::NOTIFICATIONS); |
content::WebContents* web_contents = |
browser()->tab_strip_model()->GetActiveWebContents(); |