chrome: Add support for OnRequestMediaAccessPermission callback (see issue #2582)
This commit is contained in:
parent
d9a7422346
commit
64a5754959
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=5a39566f586c012271d96c7d42337a30bf98e6b8$
|
||||
// $hash=e902fe011f8667b64989e57ad9e72aec74b22015$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_PERMISSION_HANDLER_CAPI_H_
|
||||
|
@ -106,9 +106,11 @@ typedef struct _cef_permission_handler_t {
|
|||
// combination of values from cef_media_access_permission_types_t that
|
||||
// represent the requested permissions. Return true (1) and call
|
||||
// cef_media_access_callback_t functions either in this function or at a later
|
||||
// time to continue or cancel the request. Return false (0) to cancel the
|
||||
// request immediately. This function will not be called if the "--enable-
|
||||
// media-stream" command-line switch is used to grant all permissions.
|
||||
// time to continue or cancel the request. Return false (0) to proceed with
|
||||
// default handling. With the Chrome runtime, default handling will display
|
||||
// the permission request UI. With the Alloy runtime, default handling will
|
||||
// deny the request. This function will not be called if the "--enable-media-
|
||||
// stream" command-line switch is used to grant all permissions.
|
||||
///
|
||||
int(CEF_CALLBACK* on_request_media_access_permission)(
|
||||
struct _cef_permission_handler_t* self,
|
||||
|
|
|
@ -92,8 +92,10 @@ class CefPermissionHandler : public virtual CefBaseRefCounted {
|
|||
// combination of values from cef_media_access_permission_types_t that
|
||||
// represent the requested permissions. Return true and call
|
||||
// CefMediaAccessCallback methods either in this method or at a later time to
|
||||
// continue or cancel the request. Return false to cancel the request
|
||||
// immediately. This method will not be called if the "--enable-media-stream"
|
||||
// continue or cancel the request. Return false to proceed with default
|
||||
// handling. With the Chrome runtime, default handling will display the
|
||||
// permission request UI. With the Alloy runtime, default handling will deny
|
||||
// the request. This method will not be called if the "--enable-media-stream"
|
||||
// command-line switch is used to grant all permissions.
|
||||
///
|
||||
/*--cef()--*/
|
||||
|
|
|
@ -1298,8 +1298,10 @@ void AlloyBrowserHostImpl::RequestMediaAccessPermission(
|
|||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) {
|
||||
media_access_query::RequestMediaAccessPermission(this, request,
|
||||
std::move(callback));
|
||||
auto returned_callback = media_access_query::RequestMediaAccessPermission(
|
||||
this, request, std::move(callback), /*default_disallow=*/true);
|
||||
// Callback should not be returned.
|
||||
DCHECK(returned_callback.is_null());
|
||||
}
|
||||
|
||||
bool AlloyBrowserHostImpl::CheckMediaAccessPermission(
|
||||
|
|
|
@ -55,6 +55,15 @@ class BrowserDelegate : public content::WebContentsDelegate {
|
|||
WindowOpenDisposition disposition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Same as RequestMediaAccessPermission but returning |callback| if the
|
||||
// request is unhandled.
|
||||
[[nodiscard]] virtual content::MediaResponseCallback
|
||||
RequestMediaAccessPermissionEx(content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) {
|
||||
return callback;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace cef
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "libcef/browser/browser_info_manager.h"
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#include "libcef/browser/chrome/chrome_browser_host_impl.h"
|
||||
#include "libcef/browser/media_access_query.h"
|
||||
#include "libcef/browser/request_context_impl.h"
|
||||
#include "libcef/common/app_manager.h"
|
||||
#include "libcef/common/frame_util.h"
|
||||
|
@ -102,6 +103,19 @@ bool ChromeBrowserDelegate::HandleCommand(int command_id,
|
|||
return false;
|
||||
}
|
||||
|
||||
content::MediaResponseCallback
|
||||
ChromeBrowserDelegate::RequestMediaAccessPermissionEx(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) {
|
||||
if (auto browser = ChromeBrowserHostImpl::GetBrowserForBrowser(browser_)) {
|
||||
return media_access_query::RequestMediaAccessPermission(
|
||||
browser.get(), request, std::move(callback),
|
||||
/*default_disallow=*/false);
|
||||
}
|
||||
return callback;
|
||||
}
|
||||
|
||||
void ChromeBrowserDelegate::WebContentsCreated(
|
||||
content::WebContents* source_contents,
|
||||
int opener_render_process_id,
|
||||
|
|
|
@ -54,6 +54,10 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
|
|||
bool ShowStatusBubble(bool show_by_default) override;
|
||||
bool HandleCommand(int command_id,
|
||||
WindowOpenDisposition disposition) override;
|
||||
[[nodiscard]] content::MediaResponseCallback RequestMediaAccessPermissionEx(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) override;
|
||||
|
||||
// WebContentsDelegate methods:
|
||||
void WebContentsCreated(content::WebContents* source_contents,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "libcef/browser/media_stream_registrar.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
|
||||
#include "base/callback_helpers.h"
|
||||
#include "base/command_line.h"
|
||||
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
|
||||
|
||||
|
@ -59,6 +60,10 @@ class CefMediaAccessQuery {
|
|||
return requested_permissions;
|
||||
}
|
||||
|
||||
[[nodiscard]] CallbackType DisconnectCallback() {
|
||||
return std::move(callback_);
|
||||
}
|
||||
|
||||
void ExecuteCallback(uint32_t allowed_permissions) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
|
@ -267,6 +272,7 @@ class CefMediaAccessCallbackImpl : public CefMediaAccessCallback {
|
|||
void Cancel() override { Continue(CEF_MEDIA_PERMISSION_NONE); }
|
||||
|
||||
[[nodiscard]] CallbackType Disconnect() { return std::move(callback_); }
|
||||
bool IsDisconnected() const { return callback_.is_null(); }
|
||||
|
||||
private:
|
||||
static void RunNow(CallbackType callback, uint32_t allowed_permissions) {
|
||||
|
@ -294,9 +300,11 @@ bool CheckMediaAccessPermission(CefBrowserHostBase* browser,
|
|||
return true;
|
||||
}
|
||||
|
||||
void RequestMediaAccessPermission(CefBrowserHostBase* browser,
|
||||
content::MediaResponseCallback RequestMediaAccessPermission(
|
||||
CefBrowserHostBase* browser,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) {
|
||||
content::MediaResponseCallback callback,
|
||||
bool default_disallow) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
CefMediaAccessQuery query(browser, request, std::move(callback));
|
||||
|
@ -304,10 +312,10 @@ void RequestMediaAccessPermission(CefBrowserHostBase* browser,
|
|||
if (CheckCommandLinePermission()) {
|
||||
// Allow all requested permissions.
|
||||
query.ExecuteCallback(query.requested_permissions());
|
||||
return;
|
||||
return base::NullCallback();
|
||||
}
|
||||
|
||||
bool proceed = false;
|
||||
bool handled = false;
|
||||
|
||||
if (auto client = browser->GetClient()) {
|
||||
if (auto handler = client->GetPermissionHandler()) {
|
||||
|
@ -320,18 +328,29 @@ void RequestMediaAccessPermission(CefBrowserHostBase* browser,
|
|||
request.render_process_id, request.render_frame_id));
|
||||
if (!frame)
|
||||
frame = browser->GetMainFrame();
|
||||
proceed = handler->OnRequestMediaAccessPermission(
|
||||
handled = handler->OnRequestMediaAccessPermission(
|
||||
browser, frame, request.security_origin.spec(), requested_permissions,
|
||||
callbackImpl.get());
|
||||
if (!proceed)
|
||||
if (!handled) {
|
||||
LOG_IF(ERROR, callbackImpl->IsDisconnected())
|
||||
<< "Should return true from OnRequestMediaAccessPermission when "
|
||||
"executing the callback";
|
||||
query = callbackImpl->Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!proceed && !query.is_null()) {
|
||||
if (!query.is_null()) {
|
||||
if (default_disallow && !handled) {
|
||||
// Disallow access by default.
|
||||
query.ExecuteCallback(CEF_MEDIA_PERMISSION_NONE);
|
||||
} else {
|
||||
// Proceed with default handling.
|
||||
return query.DisconnectCallback();
|
||||
}
|
||||
}
|
||||
|
||||
return base::NullCallback();
|
||||
}
|
||||
|
||||
} // namespace media_access_query
|
||||
|
|
|
@ -24,9 +24,13 @@ bool CheckMediaAccessPermission(CefBrowserHostBase* browser,
|
|||
blink::mojom::MediaStreamType type);
|
||||
|
||||
// Called from WebContentsDelegate::RequestMediaAccessPermission.
|
||||
void RequestMediaAccessPermission(CefBrowserHostBase* browser,
|
||||
// |callback| will be returned if the request is unhandled and
|
||||
// |default_disallow| is false.
|
||||
[[nodiscard]] content::MediaResponseCallback RequestMediaAccessPermission(
|
||||
CefBrowserHostBase* browser,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback);
|
||||
content::MediaResponseCallback callback,
|
||||
bool default_disallow);
|
||||
|
||||
} // namespace media_access_query
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ index 583a685cd125a..bef2272570eb1 100644
|
|||
]
|
||||
}
|
||||
diff --git chrome/browser/ui/browser.cc chrome/browser/ui/browser.cc
|
||||
index 63d64acc72318..fd3cb52daf611 100644
|
||||
index 63d64acc72318..21f0a0b81f996 100644
|
||||
--- chrome/browser/ui/browser.cc
|
||||
+++ chrome/browser/ui/browser.cc
|
||||
@@ -264,6 +264,25 @@
|
||||
|
@ -254,7 +254,23 @@ index 63d64acc72318..fd3cb52daf611 100644
|
|||
}
|
||||
|
||||
bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) {
|
||||
@@ -2664,13 +2763,20 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
|
||||
@@ -2127,6 +2226,15 @@ void Browser::RequestMediaAccessPermission(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback) {
|
||||
+#if BUILDFLAG(ENABLE_CEF)
|
||||
+ if (cef_browser_delegate_) {
|
||||
+ callback = cef_browser_delegate_->RequestMediaAccessPermissionEx(
|
||||
+ web_contents, request, std::move(callback));
|
||||
+ if (callback.is_null())
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
const extensions::Extension* extension =
|
||||
GetExtensionForOrigin(profile_, request.security_origin);
|
||||
MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
|
||||
@@ -2664,13 +2772,20 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
|
||||
// Browser, Getters for UI (private):
|
||||
|
||||
StatusBubble* Browser::GetStatusBubble() {
|
||||
|
@ -276,7 +292,7 @@ index 63d64acc72318..fd3cb52daf611 100644
|
|||
return window_ ? window_->GetStatusBubble() : nullptr;
|
||||
}
|
||||
|
||||
@@ -2797,6 +2903,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
|
||||
@@ -2797,6 +2912,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
|
||||
content_translate_driver->RemoveTranslationObserver(this);
|
||||
BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "include/wrapper/cef_stream_resource_handler.h"
|
||||
#include "tests/ceftests/test_handler.h"
|
||||
#include "tests/ceftests/test_suite.h"
|
||||
#include "tests/ceftests/test_util.h"
|
||||
#include "tests/gtest/include/gtest/gtest.h"
|
||||
#include "tests/shared/browser/client_app_browser.h"
|
||||
|
||||
|
@ -22,6 +23,8 @@ namespace {
|
|||
const char kMediaUrl[] = "https://media-access-test/media.html";
|
||||
const char kMediaOrigin[] = "https://media-access-test/";
|
||||
|
||||
constexpr char kMediaNavUrl[] = "https://media-access-test/nav.html";
|
||||
|
||||
// Browser-side app delegate.
|
||||
class MediaAccessBrowserTest : public client::ClientAppBrowser::Delegate,
|
||||
public CefPermissionHandler {
|
||||
|
@ -44,14 +47,35 @@ class TestSetup {
|
|||
public:
|
||||
TestSetup() {}
|
||||
|
||||
// CONFIGURATION
|
||||
|
||||
// Deny the prompt by returning false in OnRequestMediaAccessPermission.
|
||||
bool deny_implicitly = false;
|
||||
|
||||
// Deny the prompt by returning true in OnRequestMediaAccessPermission but
|
||||
// then never calling CefMediaAccessCallback::Continue.
|
||||
bool deny_with_navigation = false;
|
||||
|
||||
// Don't synchronously execute the callback in OnRequestMediaAccessPermission.
|
||||
bool continue_async = false;
|
||||
|
||||
// RESULTS
|
||||
|
||||
// Method callbacks.
|
||||
TrackCallback got_request;
|
||||
TrackCallback got_success;
|
||||
TrackCallback got_change;
|
||||
|
||||
// JS success state.
|
||||
TrackCallback got_js_success;
|
||||
TrackCallback got_audio;
|
||||
TrackCallback got_video;
|
||||
TrackCallback got_change;
|
||||
|
||||
// JS error state.
|
||||
TrackCallback got_js_error;
|
||||
std::string js_error_str;
|
||||
|
||||
// JS timeout state.
|
||||
TrackCallback got_js_timeout;
|
||||
};
|
||||
|
||||
class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
||||
|
@ -67,26 +91,25 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
|||
std::string newUrl = request->GetURL();
|
||||
if (newUrl.find("tests/exit") != std::string::npos) {
|
||||
if (newUrl.find("SUCCESS") != std::string::npos) {
|
||||
EXPECT_FALSE(test_setup_->got_success);
|
||||
test_setup_->got_success.yes();
|
||||
EXPECT_FALSE(test_setup_->got_js_success);
|
||||
test_setup_->got_js_success.yes();
|
||||
|
||||
std::string data_string = newUrl.substr(newUrl.find("&data=") +
|
||||
std::string("&data=").length());
|
||||
std::string data_string_decoded = CefURIDecode(
|
||||
data_string, false,
|
||||
static_cast<cef_uri_unescape_rule_t>(
|
||||
UU_SPACES | UU_URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS));
|
||||
auto obj = CefParseJSON(data_string_decoded,
|
||||
JSON_PARSER_ALLOW_TRAILING_COMMAS);
|
||||
CefRefPtr<CefDictionaryValue> data = obj->GetDictionary();
|
||||
const auto got_video = data->GetBool("got_video_track");
|
||||
const auto got_audio = data->GetBool("got_audio_track");
|
||||
if (got_video) {
|
||||
auto dict = ParseURLData(newUrl);
|
||||
if (dict->GetBool("got_video_track")) {
|
||||
test_setup_->got_video.yes();
|
||||
}
|
||||
if (got_audio) {
|
||||
if (dict->GetBool("got_audio_track")) {
|
||||
test_setup_->got_audio.yes();
|
||||
}
|
||||
} else if (newUrl.find("ERROR") != std::string::npos) {
|
||||
EXPECT_FALSE(test_setup_->got_js_error);
|
||||
test_setup_->got_js_error.yes();
|
||||
|
||||
auto dict = ParseURLData(newUrl);
|
||||
test_setup_->js_error_str = dict->GetString("error_str");
|
||||
} else if (newUrl.find("TIMEOUT") != std::string::npos) {
|
||||
EXPECT_FALSE(test_setup_->got_js_timeout);
|
||||
test_setup_->got_js_timeout.yes();
|
||||
}
|
||||
DestroyTest();
|
||||
return RV_CANCEL;
|
||||
|
@ -101,7 +124,7 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
|||
"<script>"
|
||||
"function onResult(val, data) {"
|
||||
" if(!data) {"
|
||||
" data = { got_audio_track: false, got_video_track: false};"
|
||||
" data = {};"
|
||||
" }"
|
||||
" document.location = "
|
||||
"`http://tests/"
|
||||
|
@ -120,13 +143,26 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
|||
|
||||
page +=
|
||||
".then(function(stream) {"
|
||||
"onResult(`SUCCESS`, {got_audio_track: stream.getAudioTracks().length "
|
||||
" onResult(`SUCCESS`, {got_audio_track: "
|
||||
"stream.getAudioTracks().length "
|
||||
"> 0, got_video_track: stream.getVideoTracks().length > 0});"
|
||||
"})"
|
||||
".catch(function(err) {"
|
||||
"console.log(err.toString());"
|
||||
"onResult(`FAILURE`);"
|
||||
"});"
|
||||
" console.log(err.toString());"
|
||||
" onResult(`ERROR`, {error_str: err.toString()});"
|
||||
"});";
|
||||
|
||||
if (test_setup_->deny_implicitly && IsChromeRuntimeEnabled()) {
|
||||
// Default behavior with the Chrome runtime is to show a UI prompt, so add
|
||||
// a timeout.
|
||||
page += "setTimeout(() => { onResult(`TIMEOUT`); }, 1000);";
|
||||
} else if (test_setup_->deny_with_navigation) {
|
||||
// Cancel the pending request by navigating.
|
||||
page += "setTimeout(() => { document.location = '" +
|
||||
std::string(kMediaNavUrl) + "'; }, 1000);";
|
||||
}
|
||||
|
||||
page +=
|
||||
"</script>"
|
||||
"</head><body>MEDIA ACCESS TEST</body></html>";
|
||||
|
||||
|
@ -137,6 +173,11 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
|||
|
||||
AddResource(kMediaUrl, page, "text/html");
|
||||
|
||||
if (test_setup_->deny_with_navigation) {
|
||||
AddResource(kMediaNavUrl, "<html><body>Navigated</body></html>",
|
||||
"text/html");
|
||||
}
|
||||
|
||||
// Create the browser.
|
||||
CreateBrowser(kMediaUrl, request_context);
|
||||
|
||||
|
@ -148,6 +189,16 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
|||
return this;
|
||||
}
|
||||
|
||||
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) override {
|
||||
if (test_setup_->deny_with_navigation) {
|
||||
if (frame->GetURL().ToString() == kMediaNavUrl) {
|
||||
DestroyTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OnRequestMediaAccessPermission(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
|
@ -167,6 +218,12 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (test_setup_->deny_with_navigation) {
|
||||
// Handle the request, but never execute the callback.
|
||||
callback_ = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (test_setup_->continue_async) {
|
||||
CefPostTask(TID_UI, base::BindOnce(&CefMediaAccessCallback::Continue,
|
||||
callback, response_));
|
||||
|
@ -186,6 +243,23 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
|||
test_setup_->got_change.yes();
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
callback_ = nullptr;
|
||||
|
||||
const size_t js_outcome_ct = test_setup_->got_js_success +
|
||||
test_setup_->got_js_error +
|
||||
test_setup_->got_js_timeout;
|
||||
if (test_setup_->deny_with_navigation) {
|
||||
// Expect no JS outcome.
|
||||
EXPECT_EQ(0U, js_outcome_ct);
|
||||
} else {
|
||||
// Expect a single JS outcome.
|
||||
EXPECT_EQ(1U, js_outcome_ct);
|
||||
}
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
private:
|
||||
bool want_audio_device() const {
|
||||
return request_ & CEF_MEDIA_PERMISSION_DEVICE_AUDIO_CAPTURE;
|
||||
|
@ -213,10 +287,25 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
|
|||
return response_ & CEF_MEDIA_PERMISSION_DESKTOP_VIDEO_CAPTURE;
|
||||
}
|
||||
|
||||
CefRefPtr<CefDictionaryValue> ParseURLData(const std::string& url) {
|
||||
const std::string& find_str = "&data=";
|
||||
const std::string& data_string =
|
||||
url.substr(url.find(find_str) + std::string(find_str).length());
|
||||
const std::string& data_string_decoded = CefURIDecode(
|
||||
data_string, false,
|
||||
static_cast<cef_uri_unescape_rule_t>(
|
||||
UU_SPACES | UU_URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS));
|
||||
auto obj =
|
||||
CefParseJSON(data_string_decoded, JSON_PARSER_ALLOW_TRAILING_COMMAS);
|
||||
return obj->GetDictionary();
|
||||
}
|
||||
|
||||
TestSetup* const test_setup_;
|
||||
const uint32 request_;
|
||||
const uint32 response_;
|
||||
|
||||
CefRefPtr<CefMediaAccessCallback> callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(MediaAccessTestHandler);
|
||||
};
|
||||
} // namespace
|
||||
|
@ -235,9 +324,31 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningFalse) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
if (IsChromeRuntimeEnabled()) {
|
||||
// Chrome shows a UI prompt, so we time out.
|
||||
EXPECT_TRUE(test_setup.got_js_timeout);
|
||||
} else {
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Permission denied",
|
||||
test_setup.js_error_str.c_str());
|
||||
}
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
TEST(MediaAccessTest, DeviceFailureWhenNoCallback) {
|
||||
TestSetup test_setup;
|
||||
test_setup.deny_with_navigation = true;
|
||||
|
||||
CefRefPtr<MediaAccessTestHandler> handler =
|
||||
new MediaAccessTestHandler(&test_setup,
|
||||
CEF_MEDIA_PERMISSION_DEVICE_AUDIO_CAPTURE |
|
||||
CEF_MEDIA_PERMISSION_DEVICE_VIDEO_CAPTURE,
|
||||
CEF_MEDIA_PERMISSION_NONE);
|
||||
handler->ExecuteTest();
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
// No JS result.
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -253,9 +364,9 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningNoPermission) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Permission denied",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -272,9 +383,9 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningNoPermissionAsync) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Permission denied",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -288,9 +399,9 @@ TEST(MediaAccessTest, DeviceFailureWhenRequestingAudioButReturningVideo) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -304,9 +415,9 @@ TEST(MediaAccessTest, DeviceFailureWhenRequestingVideoButReturningAudio) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -322,9 +433,9 @@ TEST(MediaAccessTest, DevicePartialFailureReturningVideo) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -340,9 +451,9 @@ TEST(MediaAccessTest, DevicePartialFailureReturningAudio) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -358,9 +469,9 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture1) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -376,9 +487,9 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture2) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -392,9 +503,9 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture3) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -408,9 +519,9 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture4) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -424,9 +535,9 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture5) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -440,9 +551,9 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture6) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -456,7 +567,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioOnly) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_TRUE(test_setup.got_success);
|
||||
EXPECT_TRUE(test_setup.got_js_success);
|
||||
EXPECT_TRUE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_change);
|
||||
|
@ -472,7 +583,7 @@ TEST(MediaAccessTest, DeviceSuccessVideoOnly) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_TRUE(test_setup.got_success);
|
||||
EXPECT_TRUE(test_setup.got_js_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_TRUE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_change);
|
||||
|
@ -491,7 +602,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioVideo) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_TRUE(test_setup.got_success);
|
||||
EXPECT_TRUE(test_setup.got_js_success);
|
||||
EXPECT_TRUE(test_setup.got_audio);
|
||||
EXPECT_TRUE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_change);
|
||||
|
@ -511,7 +622,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioVideoAsync) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_TRUE(test_setup.got_success);
|
||||
EXPECT_TRUE(test_setup.got_js_success);
|
||||
EXPECT_TRUE(test_setup.got_audio);
|
||||
EXPECT_TRUE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_change);
|
||||
|
@ -530,9 +641,9 @@ TEST(MediaAccessTest, DesktopFailureWhenReturningNoPermission) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Permission denied",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -546,9 +657,9 @@ TEST(MediaAccessTest, DesktopFailureWhenRequestingVideoButReturningAudio) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
@ -564,7 +675,7 @@ TEST(MediaAccessTest, DesktopPartialSuccessReturningVideo) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_TRUE(test_setup.got_success);
|
||||
EXPECT_TRUE(test_setup.got_js_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_TRUE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_change);
|
||||
|
@ -581,9 +692,9 @@ TEST(MediaAccessTest, DesktopPartialFailureReturningAudio) {
|
|||
ReleaseAndWaitForDestructor(handler);
|
||||
|
||||
EXPECT_TRUE(test_setup.got_request);
|
||||
EXPECT_FALSE(test_setup.got_success);
|
||||
EXPECT_FALSE(test_setup.got_audio);
|
||||
EXPECT_FALSE(test_setup.got_video);
|
||||
EXPECT_TRUE(test_setup.got_js_error);
|
||||
EXPECT_STREQ("NotAllowedError: Invalid state",
|
||||
test_setup.js_error_str.c_str());
|
||||
EXPECT_FALSE(test_setup.got_change);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue