mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	Add CefPermissionHandler callbacks for permission prompts (see issue #3352)
This commit is contained in:
		
							
								
								
									
										4
									
								
								BUILD.gn
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								BUILD.gn
									
									
									
									
									
								
							| @@ -419,8 +419,6 @@ static_library("libcef_static") { | |||||||
|     "libcef/browser/alloy/alloy_content_browser_client.h", |     "libcef/browser/alloy/alloy_content_browser_client.h", | ||||||
|     "libcef/browser/alloy/alloy_download_util.cc", |     "libcef/browser/alloy/alloy_download_util.cc", | ||||||
|     "libcef/browser/alloy/alloy_download_util.h", |     "libcef/browser/alloy/alloy_download_util.h", | ||||||
|     "libcef/browser/alloy/alloy_permission_manager.cc", |  | ||||||
|     "libcef/browser/alloy/alloy_permission_manager.h", |  | ||||||
|     "libcef/browser/alloy/alloy_web_contents_view_delegate.cc", |     "libcef/browser/alloy/alloy_web_contents_view_delegate.cc", | ||||||
|     "libcef/browser/alloy/alloy_web_contents_view_delegate.h", |     "libcef/browser/alloy/alloy_web_contents_view_delegate.h", | ||||||
|     "libcef/browser/alloy/browser_platform_delegate_alloy.cc", |     "libcef/browser/alloy/browser_platform_delegate_alloy.cc", | ||||||
| @@ -662,6 +660,8 @@ static_library("libcef_static") { | |||||||
|     "libcef/browser/osr/web_contents_view_osr.cc", |     "libcef/browser/osr/web_contents_view_osr.cc", | ||||||
|     "libcef/browser/osr/web_contents_view_osr.h", |     "libcef/browser/osr/web_contents_view_osr.h", | ||||||
|     "libcef/browser/path_util_impl.cc", |     "libcef/browser/path_util_impl.cc", | ||||||
|  |     "libcef/browser/permission_prompt.cc", | ||||||
|  |     "libcef/browser/permission_prompt.h", | ||||||
|     "libcef/browser/prefs/browser_prefs.cc", |     "libcef/browser/prefs/browser_prefs.cc", | ||||||
|     "libcef/browser/prefs/browser_prefs.h", |     "libcef/browser/prefs/browser_prefs.h", | ||||||
|     "libcef/browser/prefs/pref_store.cc", |     "libcef/browser/prefs/pref_store.cc", | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| # by hand. See the translator.README.txt file in the tools directory for | # by hand. See the translator.README.txt file in the tools directory for | ||||||
| # more information. | # more information. | ||||||
| # | # | ||||||
| # $hash=f374acb217db4183917195716d5522a9eb897cdf$ | # $hash=3ed1afd1b5f881884e6cfd0186fe41bb7b19fd38$ | ||||||
| # | # | ||||||
|  |  | ||||||
| { | { | ||||||
| @@ -374,6 +374,8 @@ | |||||||
|       'libcef_dll/ctocpp/pdf_print_callback_ctocpp.h', |       'libcef_dll/ctocpp/pdf_print_callback_ctocpp.h', | ||||||
|       'libcef_dll/ctocpp/permission_handler_ctocpp.cc', |       'libcef_dll/ctocpp/permission_handler_ctocpp.cc', | ||||||
|       'libcef_dll/ctocpp/permission_handler_ctocpp.h', |       'libcef_dll/ctocpp/permission_handler_ctocpp.h', | ||||||
|  |       'libcef_dll/cpptoc/permission_prompt_callback_cpptoc.cc', | ||||||
|  |       'libcef_dll/cpptoc/permission_prompt_callback_cpptoc.h', | ||||||
|       'libcef_dll/cpptoc/post_data_cpptoc.cc', |       'libcef_dll/cpptoc/post_data_cpptoc.cc', | ||||||
|       'libcef_dll/cpptoc/post_data_cpptoc.h', |       'libcef_dll/cpptoc/post_data_cpptoc.h', | ||||||
|       'libcef_dll/cpptoc/post_data_element_cpptoc.cc', |       'libcef_dll/cpptoc/post_data_element_cpptoc.cc', | ||||||
| @@ -690,6 +692,8 @@ | |||||||
|       'libcef_dll/cpptoc/pdf_print_callback_cpptoc.h', |       'libcef_dll/cpptoc/pdf_print_callback_cpptoc.h', | ||||||
|       'libcef_dll/cpptoc/permission_handler_cpptoc.cc', |       'libcef_dll/cpptoc/permission_handler_cpptoc.cc', | ||||||
|       'libcef_dll/cpptoc/permission_handler_cpptoc.h', |       'libcef_dll/cpptoc/permission_handler_cpptoc.h', | ||||||
|  |       'libcef_dll/ctocpp/permission_prompt_callback_ctocpp.cc', | ||||||
|  |       'libcef_dll/ctocpp/permission_prompt_callback_ctocpp.h', | ||||||
|       'libcef_dll/ctocpp/post_data_ctocpp.cc', |       'libcef_dll/ctocpp/post_data_ctocpp.cc', | ||||||
|       'libcef_dll/ctocpp/post_data_ctocpp.h', |       'libcef_dll/ctocpp/post_data_ctocpp.h', | ||||||
|       'libcef_dll/ctocpp/post_data_element_ctocpp.cc', |       'libcef_dll/ctocpp/post_data_element_ctocpp.cc', | ||||||
|   | |||||||
| @@ -493,6 +493,7 @@ | |||||||
|       'tests/ceftests/osr_display_unittest.cc', |       'tests/ceftests/osr_display_unittest.cc', | ||||||
|       'tests/ceftests/parser_unittest.cc', |       'tests/ceftests/parser_unittest.cc', | ||||||
|       'tests/ceftests/pdf_viewer_unittest.cc', |       'tests/ceftests/pdf_viewer_unittest.cc', | ||||||
|  |       'tests/ceftests/permission_prompt_unittest.cc', | ||||||
|       'tests/ceftests/preference_unittest.cc', |       'tests/ceftests/preference_unittest.cc', | ||||||
|       'tests/ceftests/print_unittest.cc', |       'tests/ceftests/print_unittest.cc', | ||||||
|       'tests/ceftests/process_message_unittest.cc', |       'tests/ceftests/process_message_unittest.cc', | ||||||
| @@ -584,6 +585,7 @@ | |||||||
|       'tests/ceftests/message_router_unittest_utils.h', |       'tests/ceftests/message_router_unittest_utils.h', | ||||||
|       'tests/ceftests/navigation_unittest.cc', |       'tests/ceftests/navigation_unittest.cc', | ||||||
|       'tests/ceftests/pdf_viewer_unittest.cc', |       'tests/ceftests/pdf_viewer_unittest.cc', | ||||||
|  |       'tests/ceftests/permission_prompt_unittest.cc', | ||||||
|       'tests/ceftests/preference_unittest.cc', |       'tests/ceftests/preference_unittest.cc', | ||||||
|       'tests/ceftests/process_message_unittest.cc', |       'tests/ceftests/process_message_unittest.cc', | ||||||
|       'tests/ceftests/request_handler_unittest.cc', |       'tests/ceftests/request_handler_unittest.cc', | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ | |||||||
| // by hand. See the translator.README.txt file in the tools directory for | // by hand. See the translator.README.txt file in the tools directory for | ||||||
| // more information. | // more information. | ||||||
| // | // | ||||||
| // $hash=e25fb66e356e1f01d67cb86433382b3318e9778d$ | // $hash=5a39566f586c012271d96c7d42337a30bf98e6b8$ | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef CEF_INCLUDE_CAPI_CEF_PERMISSION_HANDLER_CAPI_H_ | #ifndef CEF_INCLUDE_CAPI_CEF_PERMISSION_HANDLER_CAPI_H_ | ||||||
| @@ -74,6 +74,22 @@ typedef struct _cef_media_access_callback_t { | |||||||
|   void(CEF_CALLBACK* cancel)(struct _cef_media_access_callback_t* self); |   void(CEF_CALLBACK* cancel)(struct _cef_media_access_callback_t* self); | ||||||
| } cef_media_access_callback_t; | } cef_media_access_callback_t; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Callback structure used for asynchronous continuation of permission prompts. | ||||||
|  | /// | ||||||
|  | typedef struct _cef_permission_prompt_callback_t { | ||||||
|  |   /// | ||||||
|  |   // Base structure. | ||||||
|  |   /// | ||||||
|  |   cef_base_ref_counted_t base; | ||||||
|  |  | ||||||
|  |   /// | ||||||
|  |   // Complete the permissions request with the specified |result|. | ||||||
|  |   /// | ||||||
|  |   void(CEF_CALLBACK* cont)(struct _cef_permission_prompt_callback_t* self, | ||||||
|  |                            cef_permission_request_result_t result); | ||||||
|  | } cef_permission_prompt_callback_t; | ||||||
|  |  | ||||||
| /// | /// | ||||||
| // Implement this structure to handle events related to permission requests. The | // Implement this structure to handle events related to permission requests. The | ||||||
| // functions of this structure will be called on the browser process UI thread. | // functions of this structure will be called on the browser process UI thread. | ||||||
| @@ -85,11 +101,11 @@ typedef struct _cef_permission_handler_t { | |||||||
|   cef_base_ref_counted_t base; |   cef_base_ref_counted_t base; | ||||||
|  |  | ||||||
|   /// |   /// | ||||||
|   // Called when a page requests permission to access media. |requesting_url| is |   // Called when a page requests permission to access media. |requesting_origin| | ||||||
|   // the URL requesting permission. |requested_permissions| is a combination of |   // is the URL origin requesting permission. |requested_permissions| is a | ||||||
|   // values from cef_media_access_permission_types_t that represent the |   // combination of values from cef_media_access_permission_types_t that | ||||||
|   // requested permissions. Return true (1) and call |   // represent the requested permissions. Return true (1) and call | ||||||
|   // cef_media_access_callback_t::cont() either in this function or at a later |   // 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 |   // time to continue or cancel the request. Return false (0) to cancel the | ||||||
|   // request immediately. This function will not be called if the "--enable- |   // request immediately. This function will not be called if the "--enable- | ||||||
|   // media-stream" command-line switch is used to grant all permissions. |   // media-stream" command-line switch is used to grant all permissions. | ||||||
| @@ -98,9 +114,43 @@ typedef struct _cef_permission_handler_t { | |||||||
|       struct _cef_permission_handler_t* self, |       struct _cef_permission_handler_t* self, | ||||||
|       struct _cef_browser_t* browser, |       struct _cef_browser_t* browser, | ||||||
|       struct _cef_frame_t* frame, |       struct _cef_frame_t* frame, | ||||||
|       const cef_string_t* requesting_url, |       const cef_string_t* requesting_origin, | ||||||
|       uint32 requested_permissions, |       uint32 requested_permissions, | ||||||
|       struct _cef_media_access_callback_t* callback); |       struct _cef_media_access_callback_t* callback); | ||||||
|  |  | ||||||
|  |   /// | ||||||
|  |   // Called when a page should show a permission prompt. |prompt_id| uniquely | ||||||
|  |   // identifies the prompt. |requesting_origin| is the URL origin requesting | ||||||
|  |   // permission. |requested_permissions| is a combination of values from | ||||||
|  |   // cef_permission_request_types_t that represent the requested permissions. | ||||||
|  |   // Return true (1) and call cef_permission_prompt_callback_t::Continue either | ||||||
|  |   // in this function or at a later 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 prompt UI. With the Alloy | ||||||
|  |   // runtime, default handling is CEF_PERMISSION_RESULT_IGNORE. | ||||||
|  |   /// | ||||||
|  |   int(CEF_CALLBACK* on_show_permission_prompt)( | ||||||
|  |       struct _cef_permission_handler_t* self, | ||||||
|  |       struct _cef_browser_t* browser, | ||||||
|  |       uint64 prompt_id, | ||||||
|  |       const cef_string_t* requesting_origin, | ||||||
|  |       uint32 requested_permissions, | ||||||
|  |       struct _cef_permission_prompt_callback_t* callback); | ||||||
|  |  | ||||||
|  |   /// | ||||||
|  |   // Called when a permission prompt handled via OnShowPermissionPrompt is | ||||||
|  |   // dismissed. |prompt_id| will match the value that was passed to | ||||||
|  |   // OnShowPermissionPrompt. |result| will be the value passed to | ||||||
|  |   // cef_permission_prompt_callback_t::Continue or CEF_PERMISSION_RESULT_IGNORE | ||||||
|  |   // if the dialog was dismissed for other reasons such as navigation, browser | ||||||
|  |   // closure, etc. This function will not be called if OnShowPermissionPrompt | ||||||
|  |   // returned false (0) for |prompt_id|. | ||||||
|  |   /// | ||||||
|  |   void(CEF_CALLBACK* on_dismiss_permission_prompt)( | ||||||
|  |       struct _cef_permission_handler_t* self, | ||||||
|  |       struct _cef_browser_t* browser, | ||||||
|  |       uint64 prompt_id, | ||||||
|  |       cef_permission_request_result_t result); | ||||||
| } cef_permission_handler_t; | } cef_permission_handler_t; | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|   | |||||||
| @@ -42,13 +42,13 @@ | |||||||
| // way that may cause binary incompatibility with other builds. The universal | // way that may cause binary incompatibility with other builds. The universal | ||||||
| // hash value will change if any platform is affected whereas the platform hash | // hash value will change if any platform is affected whereas the platform hash | ||||||
| // values will change only if that particular platform is affected. | // values will change only if that particular platform is affected. | ||||||
| #define CEF_API_HASH_UNIVERSAL "d3fdeba02acc73ac571a1be658789f2ff770f09c" | #define CEF_API_HASH_UNIVERSAL "1f35577ebd00c5e6cc03a172bb41e3c0d820f3d1" | ||||||
| #if defined(OS_WIN) | #if defined(OS_WIN) | ||||||
| #define CEF_API_HASH_PLATFORM "94db0746536862260c9b47d54128a744dbb29fcf" | #define CEF_API_HASH_PLATFORM "99f91193dce6b93011526269c4dc5d0c32569b70" | ||||||
| #elif defined(OS_MAC) | #elif defined(OS_MAC) | ||||||
| #define CEF_API_HASH_PLATFORM "1c8d61e3bee1c974a2f71688bbdcfc0f6f01d457" | #define CEF_API_HASH_PLATFORM "316e120c0bf151de8145ee3b45ef3451e1ff60dc" | ||||||
| #elif defined(OS_LINUX) | #elif defined(OS_LINUX) | ||||||
| #define CEF_API_HASH_PLATFORM "6d9e52b9e54ded43a7e0dfcf80b6f40ec75f3215" | #define CEF_API_HASH_PLATFORM "e061aecbfbf09b9068391bdfcd80c9d5ed1faece" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|   | |||||||
| @@ -66,6 +66,19 @@ class CefMediaAccessCallback : public virtual CefBaseRefCounted { | |||||||
|   virtual void Cancel() = 0; |   virtual void Cancel() = 0; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Callback interface used for asynchronous continuation of permission prompts. | ||||||
|  | /// | ||||||
|  | /*--cef(source=library)--*/ | ||||||
|  | class CefPermissionPromptCallback : public virtual CefBaseRefCounted { | ||||||
|  |  public: | ||||||
|  |   /// | ||||||
|  |   // Complete the permissions request with the specified |result|. | ||||||
|  |   /// | ||||||
|  |   /*--cef(capi_name=cont)--*/ | ||||||
|  |   virtual void Continue(cef_permission_request_result_t result) = 0; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /// | /// | ||||||
| // Implement this interface to handle events related to permission requests. The | // Implement this interface to handle events related to permission requests. The | ||||||
| // methods of this class will be called on the browser process UI thread. | // methods of this class will be called on the browser process UI thread. | ||||||
| @@ -74,12 +87,12 @@ class CefMediaAccessCallback : public virtual CefBaseRefCounted { | |||||||
| class CefPermissionHandler : public virtual CefBaseRefCounted { | class CefPermissionHandler : public virtual CefBaseRefCounted { | ||||||
|  public: |  public: | ||||||
|   /// |   /// | ||||||
|   // Called when a page requests permission to access media. |requesting_url| is |   // Called when a page requests permission to access media. |requesting_origin| | ||||||
|   // the URL requesting permission. |requested_permissions| is a combination of |   // is the URL origin requesting permission. |requested_permissions| is a | ||||||
|   // values from cef_media_access_permission_types_t that represent the |   // combination of values from cef_media_access_permission_types_t that | ||||||
|   // requested permissions. Return true and call |   // represent the requested permissions. Return true and call | ||||||
|   // CefMediaAccessCallback::Continue() either in this method or at a later time |   // CefMediaAccessCallback methods either in this method or at a later time to | ||||||
|   // to continue or cancel the request. Return false to cancel the request |   // continue or cancel the request. Return false to cancel the request | ||||||
|   // immediately. This method will not be called if the "--enable-media-stream" |   // immediately. This method will not be called if the "--enable-media-stream" | ||||||
|   // command-line switch is used to grant all permissions. |   // command-line switch is used to grant all permissions. | ||||||
|   /// |   /// | ||||||
| @@ -87,11 +100,47 @@ class CefPermissionHandler : public virtual CefBaseRefCounted { | |||||||
|   virtual bool OnRequestMediaAccessPermission( |   virtual bool OnRequestMediaAccessPermission( | ||||||
|       CefRefPtr<CefBrowser> browser, |       CefRefPtr<CefBrowser> browser, | ||||||
|       CefRefPtr<CefFrame> frame, |       CefRefPtr<CefFrame> frame, | ||||||
|       const CefString& requesting_url, |       const CefString& requesting_origin, | ||||||
|       uint32 requested_permissions, |       uint32 requested_permissions, | ||||||
|       CefRefPtr<CefMediaAccessCallback> callback) { |       CefRefPtr<CefMediaAccessCallback> callback) { | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /// | ||||||
|  |   // Called when a page should show a permission prompt. |prompt_id| uniquely | ||||||
|  |   // identifies the prompt. |requesting_origin| is the URL origin requesting | ||||||
|  |   // permission. |requested_permissions| is a combination of values from | ||||||
|  |   // cef_permission_request_types_t that represent the requested permissions. | ||||||
|  |   // Return true and call CefPermissionPromptCallback::Continue either in this | ||||||
|  |   // method or at a later time to continue or cancel the request. Return false | ||||||
|  |   // to proceed with default handling. With the Chrome runtime, default handling | ||||||
|  |   // will display the permission prompt UI. With the Alloy runtime, default | ||||||
|  |   // handling is CEF_PERMISSION_RESULT_IGNORE. | ||||||
|  |   /// | ||||||
|  |   /*--cef()--*/ | ||||||
|  |   virtual bool OnShowPermissionPrompt( | ||||||
|  |       CefRefPtr<CefBrowser> browser, | ||||||
|  |       uint64 prompt_id, | ||||||
|  |       const CefString& requesting_origin, | ||||||
|  |       uint32 requested_permissions, | ||||||
|  |       CefRefPtr<CefPermissionPromptCallback> callback) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /// | ||||||
|  |   // Called when a permission prompt handled via OnShowPermissionPrompt is | ||||||
|  |   // dismissed. |prompt_id| will match the value that was passed to | ||||||
|  |   // OnShowPermissionPrompt. |result| will be the value passed to | ||||||
|  |   // CefPermissionPromptCallback::Continue or CEF_PERMISSION_RESULT_IGNORE if | ||||||
|  |   // the dialog was dismissed for other reasons such as navigation, browser | ||||||
|  |   // closure, etc. This method will not be called if OnShowPermissionPrompt | ||||||
|  |   // returned false for |prompt_id|. | ||||||
|  |   /// | ||||||
|  |   /*--cef()--*/ | ||||||
|  |   virtual void OnDismissPermissionPrompt( | ||||||
|  |       CefRefPtr<CefBrowser> browser, | ||||||
|  |       uint64 prompt_id, | ||||||
|  |       cef_permission_request_result_t result) {} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  // CEF_INCLUDE_CEF_PERMISSION_HANDLER_H_ | #endif  // CEF_INCLUDE_CEF_PERMISSION_HANDLER_H_ | ||||||
|   | |||||||
| @@ -3317,6 +3317,62 @@ typedef enum { | |||||||
|   CEF_MEDIA_PERMISSION_DESKTOP_VIDEO_CAPTURE = 1 << 3, |   CEF_MEDIA_PERMISSION_DESKTOP_VIDEO_CAPTURE = 1 << 3, | ||||||
| } cef_media_access_permission_types_t; | } cef_media_access_permission_types_t; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Permission types used with OnShowPermissionPrompt. Some types are | ||||||
|  | // platform-specific or only supported with the Chrome runtime. Should be kept | ||||||
|  | // in sync with Chromium's permissions::RequestType type. | ||||||
|  | /// | ||||||
|  | typedef enum { | ||||||
|  |   CEF_PERMISSION_TYPE_NONE = 0, | ||||||
|  |   CEF_PERMISSION_TYPE_ACCESSIBILITY_EVENTS = 1 << 0, | ||||||
|  |   CEF_PERMISSION_TYPE_AR_SESSION = 1 << 1, | ||||||
|  |   CEF_PERMISSION_TYPE_CAMERA_PAN_TILT_ZOOM = 1 << 2, | ||||||
|  |   CEF_PERMISSION_TYPE_CAMERA_STREAM = 1 << 3, | ||||||
|  |   CEF_PERMISSION_TYPE_CLIPBOARD = 1 << 4, | ||||||
|  |   CEF_PERMISSION_TYPE_DISK_QUOTA = 1 << 5, | ||||||
|  |   CEF_PERMISSION_TYPE_LOCAL_FONTS = 1 << 6, | ||||||
|  |   CEF_PERMISSION_TYPE_GEOLOCATION = 1 << 7, | ||||||
|  |   CEF_PERMISSION_TYPE_IDLE_DETECTION = 1 << 8, | ||||||
|  |   CEF_PERMISSION_TYPE_MIC_STREAM = 1 << 9, | ||||||
|  |   CEF_PERMISSION_TYPE_MIDI_SYSEX = 1 << 10, | ||||||
|  |   CEF_PERMISSION_TYPE_MULTIPLE_DOWNLOADS = 1 << 11, | ||||||
|  |   CEF_PERMISSION_TYPE_NOTIFICATIONS = 1 << 12, | ||||||
|  |   CEF_PERMISSION_TYPE_PROTECTED_MEDIA_IDENTIFIER = 1 << 13, | ||||||
|  |   CEF_PERMISSION_TYPE_REGISTER_PROTOCOL_HANDLER = 1 << 14, | ||||||
|  |   CEF_PERMISSION_TYPE_SECURITY_ATTESTATION = 1 << 15, | ||||||
|  |   CEF_PERMISSION_TYPE_STORAGE_ACCESS = 1 << 16, | ||||||
|  |   CEF_PERMISSION_TYPE_U2F_API_REQUEST = 1 << 17, | ||||||
|  |   CEF_PERMISSION_TYPE_VR_SESSION = 1 << 18, | ||||||
|  |   CEF_PERMISSION_TYPE_WINDOW_PLACEMENT = 1 << 19, | ||||||
|  | } cef_permission_request_types_t; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Permission request results. | ||||||
|  | /// | ||||||
|  | typedef enum { | ||||||
|  |   /// | ||||||
|  |   // Accept the permission request as an explicit user action. | ||||||
|  |   /// | ||||||
|  |   CEF_PERMISSION_RESULT_ACCEPT, | ||||||
|  |  | ||||||
|  |   /// | ||||||
|  |   // Deny the permission request as an explicit user action. | ||||||
|  |   /// | ||||||
|  |   CEF_PERMISSION_RESULT_DENY, | ||||||
|  |  | ||||||
|  |   /// | ||||||
|  |   // Dismiss the permission request as an explicit user action. | ||||||
|  |   /// | ||||||
|  |   CEF_PERMISSION_RESULT_DISMISS, | ||||||
|  |  | ||||||
|  |   /// | ||||||
|  |   // Ignore the permission request. If the prompt remains unhandled (e.g. | ||||||
|  |   // OnShowPermissionPrompt returns false and there is no default permissions | ||||||
|  |   // UI) then any related promises may remain unresolved. | ||||||
|  |   /// | ||||||
|  |   CEF_PERMISSION_RESULT_IGNORE, | ||||||
|  | } cef_permission_request_result_t; | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ | |||||||
| #include <map> | #include <map> | ||||||
| #include <utility> | #include <utility> | ||||||
|  |  | ||||||
| #include "libcef/browser/alloy/alloy_permission_manager.h" |  | ||||||
| #include "libcef/browser/download_manager_delegate.h" | #include "libcef/browser/download_manager_delegate.h" | ||||||
| #include "libcef/browser/extensions/extension_system.h" | #include "libcef/browser/extensions/extension_system.h" | ||||||
| #include "libcef/browser/prefs/browser_prefs.h" | #include "libcef/browser/prefs/browser_prefs.h" | ||||||
| @@ -23,6 +22,7 @@ | |||||||
| #include "base/strings/string_util.h" | #include "base/strings/string_util.h" | ||||||
| #include "chrome/browser/font_family_cache.h" | #include "chrome/browser/font_family_cache.h" | ||||||
| #include "chrome/browser/media/media_device_id_salt.h" | #include "chrome/browser/media/media_device_id_salt.h" | ||||||
|  | #include "chrome/browser/permissions/permission_manager_factory.h" | ||||||
| #include "chrome/browser/plugins/chrome_plugin_service_filter.h" | #include "chrome/browser/plugins/chrome_plugin_service_filter.h" | ||||||
| #include "chrome/browser/profiles/profile_key.h" | #include "chrome/browser/profiles/profile_key.h" | ||||||
| #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" | #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" | ||||||
| @@ -31,6 +31,7 @@ | |||||||
| #include "components/keyed_service/content/browser_context_dependency_manager.h" | #include "components/keyed_service/content/browser_context_dependency_manager.h" | ||||||
| #include "components/keyed_service/core/simple_dependency_manager.h" | #include "components/keyed_service/core/simple_dependency_manager.h" | ||||||
| #include "components/keyed_service/core/simple_key_map.h" | #include "components/keyed_service/core/simple_key_map.h" | ||||||
|  | #include "components/permissions/permission_manager.h" | ||||||
| #include "components/prefs/pref_service.h" | #include "components/prefs/pref_service.h" | ||||||
| #include "components/proxy_config/pref_proxy_config_tracker_impl.h" | #include "components/proxy_config/pref_proxy_config_tracker_impl.h" | ||||||
| #include "components/user_prefs/user_prefs.h" | #include "components/user_prefs/user_prefs.h" | ||||||
| @@ -381,9 +382,7 @@ content::SSLHostStateDelegate* AlloyBrowserContext::GetSSLHostStateDelegate() { | |||||||
|  |  | ||||||
| content::PermissionControllerDelegate* | content::PermissionControllerDelegate* | ||||||
| AlloyBrowserContext::GetPermissionControllerDelegate() { | AlloyBrowserContext::GetPermissionControllerDelegate() { | ||||||
|   if (!permission_manager_.get()) |   return PermissionManagerFactory::GetForProfile(this); | ||||||
|     permission_manager_ = std::make_unique<AlloyPermissionManager>(); |  | ||||||
|   return permission_manager_.get(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| content::BackgroundFetchDelegate* | content::BackgroundFetchDelegate* | ||||||
|   | |||||||
| @@ -145,8 +145,6 @@ class AlloyBrowserContext : public ChromeProfileAlloy, | |||||||
|   std::unique_ptr<content::ResourceContext> resource_context_; |   std::unique_ptr<content::ResourceContext> resource_context_; | ||||||
|  |  | ||||||
|   scoped_refptr<MediaDeviceIDSalt> media_device_id_salt_; |   scoped_refptr<MediaDeviceIDSalt> media_device_id_salt_; | ||||||
|  |  | ||||||
|   std::unique_ptr<content::PermissionControllerDelegate> permission_manager_; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  // CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_CONTEXT_H_ | #endif  // CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_CONTEXT_H_ | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| #include "libcef/browser/extensions/extension_system_factory.h" | #include "libcef/browser/extensions/extension_system_factory.h" | ||||||
| #include "libcef/browser/file_dialog_runner.h" | #include "libcef/browser/file_dialog_runner.h" | ||||||
| #include "libcef/browser/net/chrome_scheme_handler.h" | #include "libcef/browser/net/chrome_scheme_handler.h" | ||||||
|  | #include "libcef/browser/permission_prompt.h" | ||||||
| #include "libcef/browser/thread_util.h" | #include "libcef/browser/thread_util.h" | ||||||
| #include "libcef/common/app_manager.h" | #include "libcef/common/app_manager.h" | ||||||
| #include "libcef/common/extensions/extensions_util.h" | #include "libcef/common/extensions/extensions_util.h" | ||||||
| @@ -322,6 +323,7 @@ int AlloyBrowserMainParts::PreMainMessageLoopRun() { | |||||||
|  |  | ||||||
|   scheme::RegisterWebUIControllerFactory(); |   scheme::RegisterWebUIControllerFactory(); | ||||||
|   file_dialog_runner::RegisterFactory(); |   file_dialog_runner::RegisterFactory(); | ||||||
|  |   permission_prompt::RegisterCreateCallback(); | ||||||
|  |  | ||||||
| #if BUILDFLAG(ENABLE_MEDIA_FOUNDATION_WIDEVINE_CDM) || \ | #if BUILDFLAG(ENABLE_MEDIA_FOUNDATION_WIDEVINE_CDM) || \ | ||||||
|     BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) |     BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) | ||||||
|   | |||||||
| @@ -1,115 +0,0 @@ | |||||||
| // Copyright 2022 The Chromium Embedded Framework Authors. Portions copyright |  | ||||||
| // 2015 The Chromium Authors. All rights reserved. Use of this source code is |  | ||||||
| // governed by a BSD-style license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| #include "libcef/browser/alloy/alloy_permission_manager.h" |  | ||||||
|  |  | ||||||
| #include "base/callback.h" |  | ||||||
| #include "content/public/browser/permission_controller.h" |  | ||||||
| #include "content/public/browser/render_frame_host.h" |  | ||||||
| #include "third_party/blink/public/common/permissions/permission_utils.h" |  | ||||||
|  |  | ||||||
| namespace { |  | ||||||
|  |  | ||||||
| bool IsAllowed(blink::PermissionType permission) { |  | ||||||
|   return permission == blink::PermissionType::WINDOW_PLACEMENT; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| blink::mojom::PermissionStatus GetPermissionStatusFromType( |  | ||||||
|     blink::PermissionType permission) { |  | ||||||
|   return IsAllowed(permission) ? blink::mojom::PermissionStatus::GRANTED |  | ||||||
|                                : blink::mojom::PermissionStatus::DENIED; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| }  // namespace |  | ||||||
|  |  | ||||||
| void AlloyPermissionManager::RequestPermission( |  | ||||||
|     blink::PermissionType permission, |  | ||||||
|     content::RenderFrameHost* render_frame_host, |  | ||||||
|     const GURL& requesting_origin, |  | ||||||
|     bool user_gesture, |  | ||||||
|     base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) { |  | ||||||
|   if (render_frame_host->IsNestedWithinFencedFrame()) { |  | ||||||
|     std::move(callback).Run(blink::mojom::PermissionStatus::DENIED); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   std::move(callback).Run(GetPermissionStatusFromType(permission)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AlloyPermissionManager::RequestPermissions( |  | ||||||
|     const std::vector<blink::PermissionType>& permissions, |  | ||||||
|     content::RenderFrameHost* render_frame_host, |  | ||||||
|     const GURL& requesting_origin, |  | ||||||
|     bool user_gesture, |  | ||||||
|     base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> |  | ||||||
|         callback) { |  | ||||||
|   if (render_frame_host->IsNestedWithinFencedFrame()) { |  | ||||||
|     std::move(callback).Run(std::vector<blink::mojom::PermissionStatus>( |  | ||||||
|         permissions.size(), blink::mojom::PermissionStatus::DENIED)); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   std::vector<blink::mojom::PermissionStatus> result; |  | ||||||
|   for (const auto& permission : permissions) { |  | ||||||
|     result.push_back(GetPermissionStatusFromType(permission)); |  | ||||||
|   } |  | ||||||
|   std::move(callback).Run(result); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AlloyPermissionManager::RequestPermissionsFromCurrentDocument( |  | ||||||
|     const std::vector<blink::PermissionType>& permissions, |  | ||||||
|     content::RenderFrameHost* render_frame_host, |  | ||||||
|     bool user_gesture, |  | ||||||
|     base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> |  | ||||||
|         callback) { |  | ||||||
|   if (render_frame_host->IsNestedWithinFencedFrame()) { |  | ||||||
|     std::move(callback).Run(std::vector<blink::mojom::PermissionStatus>( |  | ||||||
|         permissions.size(), blink::mojom::PermissionStatus::DENIED)); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   std::vector<blink::mojom::PermissionStatus> result; |  | ||||||
|   for (const auto& permission : permissions) { |  | ||||||
|     result.push_back(GetPermissionStatusFromType(permission)); |  | ||||||
|   } |  | ||||||
|   std::move(callback).Run(result); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| blink::mojom::PermissionStatus AlloyPermissionManager::GetPermissionStatus( |  | ||||||
|     blink::PermissionType permission, |  | ||||||
|     const GURL& requesting_origin, |  | ||||||
|     const GURL& embedding_origin) { |  | ||||||
|   return GetPermissionStatusFromType(permission); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| blink::mojom::PermissionStatus |  | ||||||
| AlloyPermissionManager::GetPermissionStatusForCurrentDocument( |  | ||||||
|     blink::PermissionType permission, |  | ||||||
|     content::RenderFrameHost* render_frame_host) { |  | ||||||
|   if (render_frame_host->IsNestedWithinFencedFrame()) |  | ||||||
|     return blink::mojom::PermissionStatus::DENIED; |  | ||||||
|   return GetPermissionStatusFromType(permission); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| blink::mojom::PermissionStatus |  | ||||||
| AlloyPermissionManager::GetPermissionStatusForWorker( |  | ||||||
|     blink::PermissionType permission, |  | ||||||
|     content::RenderProcessHost* render_process_host, |  | ||||||
|     const GURL& worker_origin) { |  | ||||||
|   return GetPermissionStatusFromType(permission); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AlloyPermissionManager::ResetPermission(blink::PermissionType permission, |  | ||||||
|                                              const GURL& requesting_origin, |  | ||||||
|                                              const GURL& embedding_origin) {} |  | ||||||
|  |  | ||||||
| AlloyPermissionManager::SubscriptionId |  | ||||||
| AlloyPermissionManager::SubscribePermissionStatusChange( |  | ||||||
|     blink::PermissionType permission, |  | ||||||
|     content::RenderProcessHost* render_process_host, |  | ||||||
|     content::RenderFrameHost* render_frame_host, |  | ||||||
|     const GURL& requesting_origin, |  | ||||||
|     base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) { |  | ||||||
|   return SubscriptionId(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AlloyPermissionManager::UnsubscribePermissionStatusChange( |  | ||||||
|     SubscriptionId subscription_id) {} |  | ||||||
| @@ -1,68 +0,0 @@ | |||||||
| // Copyright 2022 The Chromium Embedded Framework Authors. Portions copyright |  | ||||||
| // 2015 The Chromium Authors. All rights reserved. Use of this source code is |  | ||||||
| // governed by a BSD-style license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| #ifndef CEF_LIBCEF_BROWSER_ALLOY_ALLOY_PERMISSION_MANAGER_H_ |  | ||||||
| #define CEF_LIBCEF_BROWSER_ALLOY_ALLOY_PERMISSION_MANAGER_H_ |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "base/callback_forward.h" |  | ||||||
| #include "content/public/browser/permission_controller_delegate.h" |  | ||||||
|  |  | ||||||
| // Permision manager implementations that only allows WINDOW_PLACEMENT API |  | ||||||
| class AlloyPermissionManager : public content::PermissionControllerDelegate { |  | ||||||
|  public: |  | ||||||
|   AlloyPermissionManager() = default; |  | ||||||
|  |  | ||||||
|   AlloyPermissionManager(const AlloyPermissionManager&) = delete; |  | ||||||
|   AlloyPermissionManager& operator=(const AlloyPermissionManager&) = delete; |  | ||||||
|  |  | ||||||
|   // PermissionManager implementation. |  | ||||||
|   void RequestPermission( |  | ||||||
|       blink::PermissionType permission, |  | ||||||
|       content::RenderFrameHost* render_frame_host, |  | ||||||
|       const GURL& requesting_origin, |  | ||||||
|       bool user_gesture, |  | ||||||
|       base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) |  | ||||||
|       override; |  | ||||||
|   void RequestPermissions( |  | ||||||
|       const std::vector<blink::PermissionType>& permission, |  | ||||||
|       content::RenderFrameHost* render_frame_host, |  | ||||||
|       const GURL& requesting_origin, |  | ||||||
|       bool user_gesture, |  | ||||||
|       base::OnceCallback< |  | ||||||
|           void(const std::vector<blink::mojom::PermissionStatus>&)> callback) |  | ||||||
|       override; |  | ||||||
|   void RequestPermissionsFromCurrentDocument( |  | ||||||
|       const std::vector<blink::PermissionType>& permissions, |  | ||||||
|       content::RenderFrameHost* render_frame_host, |  | ||||||
|       bool user_gesture, |  | ||||||
|       base::OnceCallback< |  | ||||||
|           void(const std::vector<blink::mojom::PermissionStatus>&)> callback) |  | ||||||
|       override; |  | ||||||
|   blink::mojom::PermissionStatus GetPermissionStatus( |  | ||||||
|       blink::PermissionType permission, |  | ||||||
|       const GURL& requesting_origin, |  | ||||||
|       const GURL& embedding_origin) override; |  | ||||||
|   blink::mojom::PermissionStatus GetPermissionStatusForCurrentDocument( |  | ||||||
|       blink::PermissionType permission, |  | ||||||
|       content::RenderFrameHost* render_frame_host) override; |  | ||||||
|   blink::mojom::PermissionStatus GetPermissionStatusForWorker( |  | ||||||
|       blink::PermissionType permission, |  | ||||||
|       content::RenderProcessHost* render_process_host, |  | ||||||
|       const GURL& worker_origin) override; |  | ||||||
|   void ResetPermission(blink::PermissionType permission, |  | ||||||
|                        const GURL& requesting_origin, |  | ||||||
|                        const GURL& embedding_origin) override; |  | ||||||
|   SubscriptionId SubscribePermissionStatusChange( |  | ||||||
|       blink::PermissionType permission, |  | ||||||
|       content::RenderProcessHost* render_process_host, |  | ||||||
|       content::RenderFrameHost* render_frame_host, |  | ||||||
|       const GURL& requesting_origin, |  | ||||||
|       base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) |  | ||||||
|       override; |  | ||||||
|   void UnsubscribePermissionStatusChange( |  | ||||||
|       SubscriptionId subscription_id) override; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #endif  // CEF_LIBCEF_BROWSER_ALLOY_ALLOY_PERMISSION_MANAGER_H_ |  | ||||||
| @@ -23,6 +23,7 @@ | |||||||
| #include "components/find_in_page/find_tab_helper.h" | #include "components/find_in_page/find_tab_helper.h" | ||||||
| #include "components/find_in_page/find_types.h" | #include "components/find_in_page/find_types.h" | ||||||
| #include "components/javascript_dialogs/tab_modal_dialog_manager.h" | #include "components/javascript_dialogs/tab_modal_dialog_manager.h" | ||||||
|  | #include "components/permissions/permission_request_manager.h" | ||||||
| #include "components/zoom/zoom_controller.h" | #include "components/zoom/zoom_controller.h" | ||||||
| #include "content/browser/renderer_host/render_widget_host_impl.h" | #include "content/browser/renderer_host/render_widget_host_impl.h" | ||||||
| #include "content/browser/web_contents/web_contents_impl.h" | #include "content/browser/web_contents/web_contents_impl.h" | ||||||
| @@ -178,6 +179,7 @@ void CefBrowserPlatformDelegateAlloy::BrowserCreated( | |||||||
|   DCHECK(!web_contents_->GetDelegate()); |   DCHECK(!web_contents_->GetDelegate()); | ||||||
|   web_contents_->SetDelegate(static_cast<AlloyBrowserHostImpl*>(browser)); |   web_contents_->SetDelegate(static_cast<AlloyBrowserHostImpl*>(browser)); | ||||||
|  |  | ||||||
|  |   permissions::PermissionRequestManager::CreateForWebContents(web_contents_); | ||||||
|   PrefsTabHelper::CreateForWebContents(web_contents_); |   PrefsTabHelper::CreateForWebContents(web_contents_); | ||||||
|   printing::CefPrintViewManager::CreateForWebContents(web_contents_); |   printing::CefPrintViewManager::CreateForWebContents(web_contents_); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ | |||||||
| #include "base/command_line.h" | #include "base/command_line.h" | ||||||
| #include "chrome/browser/component_updater/chrome_component_updater_configurator.h" | #include "chrome/browser/component_updater/chrome_component_updater_configurator.h" | ||||||
| #include "chrome/browser/net/system_network_context_manager.h" | #include "chrome/browser/net/system_network_context_manager.h" | ||||||
|  | #include "chrome/browser/permissions/chrome_permissions_client.h" | ||||||
| #include "chrome/browser/policy/chrome_browser_policy_connector.h" | #include "chrome/browser/policy/chrome_browser_policy_connector.h" | ||||||
| #include "chrome/browser/printing/background_printing_manager.h" | #include "chrome/browser/printing/background_printing_manager.h" | ||||||
| #include "chrome/browser/printing/print_job_manager.h" | #include "chrome/browser/printing/print_job_manager.h" | ||||||
| @@ -67,6 +68,9 @@ void ChromeBrowserProcessAlloy::Initialize() { | |||||||
|     extensions::ExtensionsBrowserClient::Set(extensions_browser_client_.get()); |     extensions::ExtensionsBrowserClient::Set(extensions_browser_client_.get()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // Make sure permissions client has been set. | ||||||
|  |   ChromePermissionsClient::GetInstance(); | ||||||
|  |  | ||||||
|   initialized_ = true; |   initialized_ = true; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #include "libcef/browser/context.h" | #include "libcef/browser/context.h" | ||||||
| #include "libcef/browser/file_dialog_runner.h" | #include "libcef/browser/file_dialog_runner.h" | ||||||
| #include "libcef/browser/net/chrome_scheme_handler.h" | #include "libcef/browser/net/chrome_scheme_handler.h" | ||||||
|  | #include "libcef/browser/permission_prompt.h" | ||||||
|  |  | ||||||
| #include "base/task/thread_pool.h" | #include "base/task/thread_pool.h" | ||||||
|  |  | ||||||
| @@ -42,4 +43,5 @@ void ChromeBrowserMainExtraPartsCef::PreMainMessageLoopRun() { | |||||||
|   scheme::RegisterWebUIControllerFactory(); |   scheme::RegisterWebUIControllerFactory(); | ||||||
|   context_menu::RegisterMenuCreatedCallback(); |   context_menu::RegisterMenuCreatedCallback(); | ||||||
|   file_dialog_runner::RegisterFactory(); |   file_dialog_runner::RegisterFactory(); | ||||||
|  |   permission_prompt::RegisterCreateCallback(); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										296
									
								
								libcef/browser/permission_prompt.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								libcef/browser/permission_prompt.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,296 @@ | |||||||
|  | // Copyright 2022 The Chromium Embedded Framework Authors. Portions copyright | ||||||
|  | // 2016 The Chromium Authors. All rights reserved. Use of this source code is | ||||||
|  | // governed by a BSD-style license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | #include "libcef/browser/permission_prompt.h" | ||||||
|  |  | ||||||
|  | #include "libcef/browser/browser_host_base.h" | ||||||
|  | #include "libcef/features/runtime.h" | ||||||
|  |  | ||||||
|  | #include "base/logging.h" | ||||||
|  | #include "base/memory/weak_ptr.h" | ||||||
|  | #include "base/notreached.h" | ||||||
|  | #include "chrome/browser/ui/permission_bubble/permission_prompt.h" | ||||||
|  |  | ||||||
|  | namespace permission_prompt { | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  |  | ||||||
|  | uint64_t g_next_prompt_id = 0; | ||||||
|  |  | ||||||
|  | using DelegateCallback = | ||||||
|  |     base::OnceCallback<void(cef_permission_request_result_t)>; | ||||||
|  |  | ||||||
|  | class CefPermissionPromptCallbackImpl : public CefPermissionPromptCallback { | ||||||
|  |  public: | ||||||
|  |   using CallbackType = base::OnceCallback<void(cef_permission_request_result_t, | ||||||
|  |                                                bool /*notify_delegate*/)>; | ||||||
|  |  | ||||||
|  |   explicit CefPermissionPromptCallbackImpl(CallbackType&& callback) | ||||||
|  |       : callback_(std::move(callback)) {} | ||||||
|  |  | ||||||
|  |   CefPermissionPromptCallbackImpl(const CefPermissionPromptCallbackImpl&) = | ||||||
|  |       delete; | ||||||
|  |   CefPermissionPromptCallbackImpl& operator=( | ||||||
|  |       const CefPermissionPromptCallbackImpl&) = delete; | ||||||
|  |  | ||||||
|  |   // Don't need to execute the callback in this destructor because this object | ||||||
|  |   // will always be kept alive until after the CefPermissionPrompt is destroyed, | ||||||
|  |   // and that object will disconnect/execute the callback in its destructor. | ||||||
|  |   ~CefPermissionPromptCallbackImpl() override = default; | ||||||
|  |  | ||||||
|  |   void Continue(cef_permission_request_result_t result) override { | ||||||
|  |     if (CEF_CURRENTLY_ON_UIT()) { | ||||||
|  |       if (!callback_.is_null()) { | ||||||
|  |         auto callback = base::BindOnce(std::move(callback_), result, | ||||||
|  |                                        /*notify_delegate=*/true); | ||||||
|  |         if (safe_to_run_sync_) { | ||||||
|  |           std::move(callback).Run(); | ||||||
|  |         } else { | ||||||
|  |           CEF_POST_TASK(CEF_UIT, std::move(callback)); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       CEF_POST_TASK(CEF_UIT, | ||||||
|  |                     base::BindOnce(&CefPermissionPromptCallbackImpl::Continue, | ||||||
|  |                                    this, result)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] CallbackType Disconnect() { return std::move(callback_); } | ||||||
|  |   bool IsDisconnected() const { return callback_.is_null(); } | ||||||
|  |  | ||||||
|  |   void MarkSafeToRunSync() { safe_to_run_sync_ = true; } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   // Callback execution from inside CreatePermissionPromptImpl must be async, | ||||||
|  |   // otherwise PermissionRequestManager state will be incorrect. | ||||||
|  |   bool safe_to_run_sync_ = false; | ||||||
|  |  | ||||||
|  |   CallbackType callback_; | ||||||
|  |  | ||||||
|  |   IMPLEMENT_REFCOUNTING(CefPermissionPromptCallbackImpl); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Implementation based on PermissionPromptAndroid. | ||||||
|  | class CefPermissionPrompt : public permissions::PermissionPrompt { | ||||||
|  |  public: | ||||||
|  |   explicit CefPermissionPrompt(Delegate* delegate) : delegate_(delegate) { | ||||||
|  |     DCHECK(delegate_); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   CefPermissionPrompt(const CefPermissionPrompt&) = delete; | ||||||
|  |   CefPermissionPrompt& operator=(const CefPermissionPrompt&) = delete; | ||||||
|  |  | ||||||
|  |   // Expect to be destroyed (and the UI needs to go) when: | ||||||
|  |   // 1. A navigation happens, tab/webcontents is being closed; with the current | ||||||
|  |   //    GetTabSwitchingBehavior() implementation, this instance survives the tab | ||||||
|  |   //    being backgrounded. | ||||||
|  |   // 2. The permission request is resolved (accept, deny, dismiss). | ||||||
|  |   // 3. A higher priority request comes in. | ||||||
|  |   ~CefPermissionPrompt() override { | ||||||
|  |     CEF_REQUIRE_UIT(); | ||||||
|  |     if (callback_) { | ||||||
|  |       // If the callback is non-null at this point then we still need to execute | ||||||
|  |       // it in order to notify the client. | ||||||
|  |       auto callback = callback_->Disconnect(); | ||||||
|  |       if (!callback.is_null()) { | ||||||
|  |         std::move(callback).Run(CEF_PERMISSION_RESULT_IGNORE, | ||||||
|  |                                 /*notify_delegate=*/false); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Used to associate the client callback when OnShowPermissionPrompt is | ||||||
|  |   // handled. | ||||||
|  |   void AttachClientCallback( | ||||||
|  |       CefRefPtr<CefPermissionPromptCallbackImpl> callback) { | ||||||
|  |     DCHECK(callback); | ||||||
|  |     callback_ = callback; | ||||||
|  |     callback_->MarkSafeToRunSync(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Used to tie Delegate access to this object's lifespan. | ||||||
|  |   DelegateCallback MakeDelegateCallback() const { | ||||||
|  |     return base::BindOnce(&CefPermissionPrompt::NotifyDelegate, | ||||||
|  |                           weak_ptr_factory_.GetWeakPtr()); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // PermissionPrompt methods: | ||||||
|  |   void UpdateAnchor() override { NOTIMPLEMENTED(); } | ||||||
|  |   TabSwitchingBehavior GetTabSwitchingBehavior() override { | ||||||
|  |     return TabSwitchingBehavior::kKeepPromptAlive; | ||||||
|  |   } | ||||||
|  |   permissions::PermissionPromptDisposition GetPromptDisposition() | ||||||
|  |       const override { | ||||||
|  |     return permissions::PermissionPromptDisposition::CUSTOM_MODAL_DIALOG; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   // We don't expose AcceptThisTime() because it's a special case for | ||||||
|  |   // Geolocation (see DCHECK in PrefProvider::SetWebsiteSetting). | ||||||
|  |   void NotifyDelegate(cef_permission_request_result_t result) { | ||||||
|  |     switch (result) { | ||||||
|  |       case CEF_PERMISSION_RESULT_ACCEPT: | ||||||
|  |         delegate_->Accept(); | ||||||
|  |         break; | ||||||
|  |       case CEF_PERMISSION_RESULT_DENY: | ||||||
|  |         delegate_->Deny(); | ||||||
|  |         break; | ||||||
|  |       case CEF_PERMISSION_RESULT_DISMISS: | ||||||
|  |         delegate_->Dismiss(); | ||||||
|  |         break; | ||||||
|  |       case CEF_PERMISSION_RESULT_IGNORE: | ||||||
|  |         delegate_->Ignore(); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // |delegate_| is the PermissionRequestManager, which owns this object. | ||||||
|  |   const raw_ptr<Delegate> delegate_; | ||||||
|  |  | ||||||
|  |   CefRefPtr<CefPermissionPromptCallbackImpl> callback_; | ||||||
|  |  | ||||||
|  |   base::WeakPtrFactory<CefPermissionPrompt> weak_ptr_factory_{this}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // |notify_delegate| will be false if called from the CefPermissionPrompt | ||||||
|  | // destructor. | ||||||
|  | void ExecuteResult(CefRefPtr<CefBrowserHostBase> browser, | ||||||
|  |                    uint64_t prompt_id, | ||||||
|  |                    DelegateCallback delegate_callback, | ||||||
|  |                    cef_permission_request_result_t result, | ||||||
|  |                    bool notify_delegate) { | ||||||
|  |   CEF_REQUIRE_UIT(); | ||||||
|  |  | ||||||
|  |   if (auto client = browser->GetClient()) { | ||||||
|  |     if (auto handler = client->GetPermissionHandler()) { | ||||||
|  |       handler->OnDismissPermissionPrompt(browser, prompt_id, result); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (notify_delegate) { | ||||||
|  |     // Will be a no-op if this executes after the CefPermissionPrompt was | ||||||
|  |     // destroyed. | ||||||
|  |     std::move(delegate_callback).Run(result); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | cef_permission_request_types_t GetCefRequestType( | ||||||
|  |     permissions::RequestType type) { | ||||||
|  |   switch (type) { | ||||||
|  |     case permissions::RequestType::kAccessibilityEvents: | ||||||
|  |       return CEF_PERMISSION_TYPE_ACCESSIBILITY_EVENTS; | ||||||
|  |     case permissions::RequestType::kArSession: | ||||||
|  |       return CEF_PERMISSION_TYPE_AR_SESSION; | ||||||
|  |     case permissions::RequestType::kCameraPanTiltZoom: | ||||||
|  |       return CEF_PERMISSION_TYPE_CAMERA_PAN_TILT_ZOOM; | ||||||
|  |     case permissions::RequestType::kCameraStream: | ||||||
|  |       return CEF_PERMISSION_TYPE_CAMERA_STREAM; | ||||||
|  |     case permissions::RequestType::kClipboard: | ||||||
|  |       return CEF_PERMISSION_TYPE_CLIPBOARD; | ||||||
|  |     case permissions::RequestType::kDiskQuota: | ||||||
|  |       return CEF_PERMISSION_TYPE_DISK_QUOTA; | ||||||
|  |     case permissions::RequestType::kLocalFonts: | ||||||
|  |       return CEF_PERMISSION_TYPE_LOCAL_FONTS; | ||||||
|  |     case permissions::RequestType::kGeolocation: | ||||||
|  |       return CEF_PERMISSION_TYPE_GEOLOCATION; | ||||||
|  |     case permissions::RequestType::kIdleDetection: | ||||||
|  |       return CEF_PERMISSION_TYPE_IDLE_DETECTION; | ||||||
|  |     case permissions::RequestType::kMicStream: | ||||||
|  |       return CEF_PERMISSION_TYPE_MIC_STREAM; | ||||||
|  |     case permissions::RequestType::kMidiSysex: | ||||||
|  |       return CEF_PERMISSION_TYPE_MIDI_SYSEX; | ||||||
|  |     case permissions::RequestType::kMultipleDownloads: | ||||||
|  |       return CEF_PERMISSION_TYPE_MULTIPLE_DOWNLOADS; | ||||||
|  |     case permissions::RequestType::kNotifications: | ||||||
|  |       return CEF_PERMISSION_TYPE_NOTIFICATIONS; | ||||||
|  | #if BUILDFLAG(IS_WIN) | ||||||
|  |     case permissions::RequestType::kProtectedMediaIdentifier: | ||||||
|  |       return CEF_PERMISSION_TYPE_PROTECTED_MEDIA_IDENTIFIER; | ||||||
|  | #endif | ||||||
|  |     case permissions::RequestType::kRegisterProtocolHandler: | ||||||
|  |       return CEF_PERMISSION_TYPE_REGISTER_PROTOCOL_HANDLER; | ||||||
|  |     case permissions::RequestType::kSecurityAttestation: | ||||||
|  |       return CEF_PERMISSION_TYPE_SECURITY_ATTESTATION; | ||||||
|  |     case permissions::RequestType::kStorageAccess: | ||||||
|  |       return CEF_PERMISSION_TYPE_STORAGE_ACCESS; | ||||||
|  |     case permissions::RequestType::kU2fApiRequest: | ||||||
|  |       return CEF_PERMISSION_TYPE_U2F_API_REQUEST; | ||||||
|  |     case permissions::RequestType::kVrSession: | ||||||
|  |       return CEF_PERMISSION_TYPE_VR_SESSION; | ||||||
|  |     case permissions::RequestType::kWindowPlacement: | ||||||
|  |       return CEF_PERMISSION_TYPE_WINDOW_PLACEMENT; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   NOTREACHED(); | ||||||
|  |   return CEF_PERMISSION_TYPE_NONE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t GetRequestedPermissions( | ||||||
|  |     permissions::PermissionPrompt::Delegate* delegate) { | ||||||
|  |   uint32_t permissions = CEF_PERMISSION_TYPE_NONE; | ||||||
|  |   for (const auto* request : delegate->Requests()) { | ||||||
|  |     permissions |= GetCefRequestType(request->request_type()); | ||||||
|  |   } | ||||||
|  |   return permissions; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::unique_ptr<permissions::PermissionPrompt> CreatePermissionPromptImpl( | ||||||
|  |     content::WebContents* web_contents, | ||||||
|  |     permissions::PermissionPrompt::Delegate* delegate, | ||||||
|  |     bool* default_handling) { | ||||||
|  |   CEF_REQUIRE_UIT(); | ||||||
|  |  | ||||||
|  |   if (auto browser = CefBrowserHostBase::GetBrowserForContents(web_contents)) { | ||||||
|  |     if (auto client = browser->GetClient()) { | ||||||
|  |       if (auto handler = client->GetPermissionHandler()) { | ||||||
|  |         auto permission_prompt = | ||||||
|  |             std::make_unique<CefPermissionPrompt>(delegate); | ||||||
|  |  | ||||||
|  |         const auto prompt_id = ++g_next_prompt_id; | ||||||
|  |         auto callback = | ||||||
|  |             base::BindOnce(&ExecuteResult, browser, prompt_id, | ||||||
|  |                            permission_prompt->MakeDelegateCallback()); | ||||||
|  |  | ||||||
|  |         CefRefPtr<CefPermissionPromptCallbackImpl> callbackImpl( | ||||||
|  |             new CefPermissionPromptCallbackImpl(std::move(callback))); | ||||||
|  |         bool handled = handler->OnShowPermissionPrompt( | ||||||
|  |             browser, prompt_id, delegate->GetRequestingOrigin().spec(), | ||||||
|  |             GetRequestedPermissions(delegate), callbackImpl.get()); | ||||||
|  |  | ||||||
|  |         if (callbackImpl->IsDisconnected() || handled) { | ||||||
|  |           // Callback execution will be async. | ||||||
|  |           LOG_IF(ERROR, !handled) | ||||||
|  |               << "Should return true from OnShowPermissionPrompt when " | ||||||
|  |                  "executing the callback"; | ||||||
|  |           *default_handling = false; | ||||||
|  |           permission_prompt->AttachClientCallback(callbackImpl); | ||||||
|  |           return permission_prompt; | ||||||
|  |         } else { | ||||||
|  |           // Proceed with default handling. |callback| is discarded without | ||||||
|  |           // execution. | ||||||
|  |           callback = callbackImpl->Disconnect(); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (cef::IsAlloyRuntimeEnabled()) { | ||||||
|  |     LOG(INFO) << "Implement OnShowPermissionPrompt to override default IGNORE " | ||||||
|  |                  "handling of permission prompts."; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Proceed with default handling. This will be IGNORE with the Alloy runtime | ||||||
|  |   // and default UI prompt with the Chrome runtime. | ||||||
|  |   *default_handling = true; | ||||||
|  |   return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace | ||||||
|  |  | ||||||
|  | void RegisterCreateCallback() { | ||||||
|  |   SetCreatePermissionPromptFunction(&CreatePermissionPromptImpl); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace permission_prompt | ||||||
							
								
								
									
										15
									
								
								libcef/browser/permission_prompt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								libcef/browser/permission_prompt.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | // Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style license that can be found | ||||||
|  | // in the LICENSE file. | ||||||
|  |  | ||||||
|  | #ifndef CEF_LIBCEF_BROWSER_PERMISSION_PROMPT_H_ | ||||||
|  | #define CEF_LIBCEF_BROWSER_PERMISSION_PROMPT_H_ | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | namespace permission_prompt { | ||||||
|  |  | ||||||
|  | void RegisterCreateCallback(); | ||||||
|  |  | ||||||
|  | }  // namespace permission_prompt | ||||||
|  |  | ||||||
|  | #endif  // CEF_LIBCEF_BROWSER_PERMISSION_PROMPT_H_ | ||||||
| @@ -23,6 +23,7 @@ | |||||||
| #include "chrome/browser/first_party_sets/first_party_sets_pref_names.h" | #include "chrome/browser/first_party_sets/first_party_sets_pref_names.h" | ||||||
| #include "chrome/browser/media/media_device_id_salt.h" | #include "chrome/browser/media/media_device_id_salt.h" | ||||||
| #include "chrome/browser/media/router/media_router_feature.h" | #include "chrome/browser/media/router/media_router_feature.h" | ||||||
|  | #include "chrome/browser/media/webrtc/permission_bubble_media_access_handler.h" | ||||||
| #include "chrome/browser/net/profile_network_context_service.h" | #include "chrome/browser/net/profile_network_context_service.h" | ||||||
| #include "chrome/browser/net/system_network_context_manager.h" | #include "chrome/browser/net/system_network_context_manager.h" | ||||||
| #include "chrome/browser/plugins/plugin_info_host_impl.h" | #include "chrome/browser/plugins/plugin_info_host_impl.h" | ||||||
| @@ -46,6 +47,7 @@ | |||||||
| #include "components/keyed_service/content/browser_context_dependency_manager.h" | #include "components/keyed_service/content/browser_context_dependency_manager.h" | ||||||
| #include "components/language/core/browser/language_prefs.h" | #include "components/language/core/browser/language_prefs.h" | ||||||
| #include "components/language/core/browser/pref_names.h" | #include "components/language/core/browser/pref_names.h" | ||||||
|  | #include "components/permissions/permission_actions_history.h" | ||||||
| #include "components/pref_registry/pref_registry_syncable.h" | #include "components/pref_registry/pref_registry_syncable.h" | ||||||
| #include "components/prefs/json_pref_store.h" | #include "components/prefs/json_pref_store.h" | ||||||
| #include "components/prefs/pref_filter.h" | #include "components/prefs/pref_filter.h" | ||||||
| @@ -224,6 +226,7 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile, | |||||||
|   certificate_transparency::prefs::RegisterPrefs(registry.get()); |   certificate_transparency::prefs::RegisterPrefs(registry.get()); | ||||||
|   flags_ui::PrefServiceFlagsStorage::RegisterPrefs(registry.get()); |   flags_ui::PrefServiceFlagsStorage::RegisterPrefs(registry.get()); | ||||||
|   media_router::RegisterLocalStatePrefs(registry.get()); |   media_router::RegisterLocalStatePrefs(registry.get()); | ||||||
|  |   permissions::PermissionActionsHistory::RegisterProfilePrefs(registry.get()); | ||||||
|   PluginInfoHostImpl::RegisterUserPrefs(registry.get()); |   PluginInfoHostImpl::RegisterUserPrefs(registry.get()); | ||||||
|   PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get()); |   PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get()); | ||||||
|   ProfileNetworkContextService::RegisterLocalStatePrefs(registry.get()); |   ProfileNetworkContextService::RegisterLocalStatePrefs(registry.get()); | ||||||
| @@ -269,6 +272,7 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile, | |||||||
|     language::LanguagePrefs::RegisterProfilePrefs(registry.get()); |     language::LanguagePrefs::RegisterProfilePrefs(registry.get()); | ||||||
|     media_router::RegisterProfilePrefs(registry.get()); |     media_router::RegisterProfilePrefs(registry.get()); | ||||||
|     MediaDeviceIDSalt::RegisterProfilePrefs(registry.get()); |     MediaDeviceIDSalt::RegisterProfilePrefs(registry.get()); | ||||||
|  |     PermissionBubbleMediaAccessHandler::RegisterProfilePrefs(registry.get()); | ||||||
|     prefetch::RegisterPredictionOptionsProfilePrefs(registry.get()); |     prefetch::RegisterPredictionOptionsProfilePrefs(registry.get()); | ||||||
|     ProfileNetworkContextService::RegisterProfilePrefs(registry.get()); |     ProfileNetworkContextService::RegisterProfilePrefs(registry.get()); | ||||||
|     safe_browsing::RegisterProfilePrefs(registry.get()); |     safe_browsing::RegisterProfilePrefs(registry.get()); | ||||||
|   | |||||||
| @@ -9,13 +9,14 @@ | |||||||
| // implementations. See the translator.README.txt file in the tools directory | // implementations. See the translator.README.txt file in the tools directory | ||||||
| // for more information. | // for more information. | ||||||
| // | // | ||||||
| // $hash=9c8d3c2295998f7a976967aa7f4b6a6da7c5c53d$ | // $hash=f137c0d7ae5fef1a6478f9416f6fe3d12a66d975$ | ||||||
| // | // | ||||||
|  |  | ||||||
| #include "libcef_dll/cpptoc/permission_handler_cpptoc.h" | #include "libcef_dll/cpptoc/permission_handler_cpptoc.h" | ||||||
| #include "libcef_dll/ctocpp/browser_ctocpp.h" | #include "libcef_dll/ctocpp/browser_ctocpp.h" | ||||||
| #include "libcef_dll/ctocpp/frame_ctocpp.h" | #include "libcef_dll/ctocpp/frame_ctocpp.h" | ||||||
| #include "libcef_dll/ctocpp/media_access_callback_ctocpp.h" | #include "libcef_dll/ctocpp/media_access_callback_ctocpp.h" | ||||||
|  | #include "libcef_dll/ctocpp/permission_prompt_callback_ctocpp.h" | ||||||
| #include "libcef_dll/shutdown_checker.h" | #include "libcef_dll/shutdown_checker.h" | ||||||
|  |  | ||||||
| namespace { | namespace { | ||||||
| @@ -26,7 +27,7 @@ int CEF_CALLBACK permission_handler_on_request_media_access_permission( | |||||||
|     struct _cef_permission_handler_t* self, |     struct _cef_permission_handler_t* self, | ||||||
|     cef_browser_t* browser, |     cef_browser_t* browser, | ||||||
|     cef_frame_t* frame, |     cef_frame_t* frame, | ||||||
|     const cef_string_t* requesting_url, |     const cef_string_t* requesting_origin, | ||||||
|     uint32 requested_permissions, |     uint32 requested_permissions, | ||||||
|     cef_media_access_callback_t* callback) { |     cef_media_access_callback_t* callback) { | ||||||
|   shutdown_checker::AssertNotShutdown(); |   shutdown_checker::AssertNotShutdown(); | ||||||
| @@ -44,9 +45,9 @@ int CEF_CALLBACK permission_handler_on_request_media_access_permission( | |||||||
|   DCHECK(frame); |   DCHECK(frame); | ||||||
|   if (!frame) |   if (!frame) | ||||||
|     return 0; |     return 0; | ||||||
|   // Verify param: requesting_url; type: string_byref_const |   // Verify param: requesting_origin; type: string_byref_const | ||||||
|   DCHECK(requesting_url); |   DCHECK(requesting_origin); | ||||||
|   if (!requesting_url) |   if (!requesting_origin) | ||||||
|     return 0; |     return 0; | ||||||
|   // Verify param: callback; type: refptr_diff |   // Verify param: callback; type: refptr_diff | ||||||
|   DCHECK(callback); |   DCHECK(callback); | ||||||
| @@ -57,13 +58,71 @@ int CEF_CALLBACK permission_handler_on_request_media_access_permission( | |||||||
|   bool _retval = |   bool _retval = | ||||||
|       CefPermissionHandlerCppToC::Get(self)->OnRequestMediaAccessPermission( |       CefPermissionHandlerCppToC::Get(self)->OnRequestMediaAccessPermission( | ||||||
|           CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame), |           CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame), | ||||||
|           CefString(requesting_url), requested_permissions, |           CefString(requesting_origin), requested_permissions, | ||||||
|           CefMediaAccessCallbackCToCpp::Wrap(callback)); |           CefMediaAccessCallbackCToCpp::Wrap(callback)); | ||||||
|  |  | ||||||
|   // Return type: bool |   // Return type: bool | ||||||
|   return _retval; |   return _retval; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int CEF_CALLBACK permission_handler_on_show_permission_prompt( | ||||||
|  |     struct _cef_permission_handler_t* self, | ||||||
|  |     cef_browser_t* browser, | ||||||
|  |     uint64 prompt_id, | ||||||
|  |     const cef_string_t* requesting_origin, | ||||||
|  |     uint32 requested_permissions, | ||||||
|  |     cef_permission_prompt_callback_t* callback) { | ||||||
|  |   shutdown_checker::AssertNotShutdown(); | ||||||
|  |  | ||||||
|  |   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING | ||||||
|  |  | ||||||
|  |   DCHECK(self); | ||||||
|  |   if (!self) | ||||||
|  |     return 0; | ||||||
|  |   // Verify param: browser; type: refptr_diff | ||||||
|  |   DCHECK(browser); | ||||||
|  |   if (!browser) | ||||||
|  |     return 0; | ||||||
|  |   // Verify param: requesting_origin; type: string_byref_const | ||||||
|  |   DCHECK(requesting_origin); | ||||||
|  |   if (!requesting_origin) | ||||||
|  |     return 0; | ||||||
|  |   // Verify param: callback; type: refptr_diff | ||||||
|  |   DCHECK(callback); | ||||||
|  |   if (!callback) | ||||||
|  |     return 0; | ||||||
|  |  | ||||||
|  |   // Execute | ||||||
|  |   bool _retval = CefPermissionHandlerCppToC::Get(self)->OnShowPermissionPrompt( | ||||||
|  |       CefBrowserCToCpp::Wrap(browser), prompt_id, CefString(requesting_origin), | ||||||
|  |       requested_permissions, CefPermissionPromptCallbackCToCpp::Wrap(callback)); | ||||||
|  |  | ||||||
|  |   // Return type: bool | ||||||
|  |   return _retval; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void CEF_CALLBACK permission_handler_on_dismiss_permission_prompt( | ||||||
|  |     struct _cef_permission_handler_t* self, | ||||||
|  |     cef_browser_t* browser, | ||||||
|  |     uint64 prompt_id, | ||||||
|  |     cef_permission_request_result_t result) { | ||||||
|  |   shutdown_checker::AssertNotShutdown(); | ||||||
|  |  | ||||||
|  |   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING | ||||||
|  |  | ||||||
|  |   DCHECK(self); | ||||||
|  |   if (!self) | ||||||
|  |     return; | ||||||
|  |   // Verify param: browser; type: refptr_diff | ||||||
|  |   DCHECK(browser); | ||||||
|  |   if (!browser) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   // Execute | ||||||
|  |   CefPermissionHandlerCppToC::Get(self)->OnDismissPermissionPrompt( | ||||||
|  |       CefBrowserCToCpp::Wrap(browser), prompt_id, result); | ||||||
|  | } | ||||||
|  |  | ||||||
| }  // namespace | }  // namespace | ||||||
|  |  | ||||||
| // CONSTRUCTOR - Do not edit by hand. | // CONSTRUCTOR - Do not edit by hand. | ||||||
| @@ -71,6 +130,10 @@ int CEF_CALLBACK permission_handler_on_request_media_access_permission( | |||||||
| CefPermissionHandlerCppToC::CefPermissionHandlerCppToC() { | CefPermissionHandlerCppToC::CefPermissionHandlerCppToC() { | ||||||
|   GetStruct()->on_request_media_access_permission = |   GetStruct()->on_request_media_access_permission = | ||||||
|       permission_handler_on_request_media_access_permission; |       permission_handler_on_request_media_access_permission; | ||||||
|  |   GetStruct()->on_show_permission_prompt = | ||||||
|  |       permission_handler_on_show_permission_prompt; | ||||||
|  |   GetStruct()->on_dismiss_permission_prompt = | ||||||
|  |       permission_handler_on_dismiss_permission_prompt; | ||||||
| } | } | ||||||
|  |  | ||||||
| // DESTRUCTOR - Do not edit by hand. | // DESTRUCTOR - Do not edit by hand. | ||||||
|   | |||||||
							
								
								
									
										66
									
								
								libcef_dll/cpptoc/permission_prompt_callback_cpptoc.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								libcef_dll/cpptoc/permission_prompt_callback_cpptoc.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | // Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights | ||||||
|  | // reserved. Use of this source code is governed by a BSD-style license that | ||||||
|  | // can be found in the LICENSE file. | ||||||
|  | // | ||||||
|  | // --------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // This file was generated by the CEF translator tool. If making changes by | ||||||
|  | // hand only do so within the body of existing method and function | ||||||
|  | // implementations. See the translator.README.txt file in the tools directory | ||||||
|  | // for more information. | ||||||
|  | // | ||||||
|  | // $hash=e2297d672c66d4530e85d4c4761d1adeabe7134c$ | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "libcef_dll/cpptoc/permission_prompt_callback_cpptoc.h" | ||||||
|  | #include "libcef_dll/shutdown_checker.h" | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  |  | ||||||
|  | // MEMBER FUNCTIONS - Body may be edited by hand. | ||||||
|  |  | ||||||
|  | void CEF_CALLBACK | ||||||
|  | permission_prompt_callback_cont(struct _cef_permission_prompt_callback_t* self, | ||||||
|  |                                 cef_permission_request_result_t result) { | ||||||
|  |   shutdown_checker::AssertNotShutdown(); | ||||||
|  |  | ||||||
|  |   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING | ||||||
|  |  | ||||||
|  |   DCHECK(self); | ||||||
|  |   if (!self) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   // Execute | ||||||
|  |   CefPermissionPromptCallbackCppToC::Get(self)->Continue(result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace | ||||||
|  |  | ||||||
|  | // CONSTRUCTOR - Do not edit by hand. | ||||||
|  |  | ||||||
|  | CefPermissionPromptCallbackCppToC::CefPermissionPromptCallbackCppToC() { | ||||||
|  |   GetStruct()->cont = permission_prompt_callback_cont; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DESTRUCTOR - Do not edit by hand. | ||||||
|  |  | ||||||
|  | CefPermissionPromptCallbackCppToC::~CefPermissionPromptCallbackCppToC() { | ||||||
|  |   shutdown_checker::AssertNotShutdown(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <> | ||||||
|  | CefRefPtr<CefPermissionPromptCallback> | ||||||
|  | CefCppToCRefCounted<CefPermissionPromptCallbackCppToC, | ||||||
|  |                     CefPermissionPromptCallback, | ||||||
|  |                     cef_permission_prompt_callback_t>:: | ||||||
|  |     UnwrapDerived(CefWrapperType type, cef_permission_prompt_callback_t* s) { | ||||||
|  |   NOTREACHED() << "Unexpected class type: " << type; | ||||||
|  |   return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <> | ||||||
|  | CefWrapperType | ||||||
|  |     CefCppToCRefCounted<CefPermissionPromptCallbackCppToC, | ||||||
|  |                         CefPermissionPromptCallback, | ||||||
|  |                         cef_permission_prompt_callback_t>::kWrapperType = | ||||||
|  |         WT_PERMISSION_PROMPT_CALLBACK; | ||||||
							
								
								
									
										38
									
								
								libcef_dll/cpptoc/permission_prompt_callback_cpptoc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								libcef_dll/cpptoc/permission_prompt_callback_cpptoc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | // Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights | ||||||
|  | // reserved. Use of this source code is governed by a BSD-style license that | ||||||
|  | // can be found in the LICENSE file. | ||||||
|  | // | ||||||
|  | // --------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // This file was generated by the CEF translator tool. If making changes by | ||||||
|  | // hand only do so within the body of existing method and function | ||||||
|  | // implementations. See the translator.README.txt file in the tools directory | ||||||
|  | // for more information. | ||||||
|  | // | ||||||
|  | // $hash=03956400a2d9931dd114105e8512b8e87d31f305$ | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef CEF_LIBCEF_DLL_CPPTOC_PERMISSION_PROMPT_CALLBACK_CPPTOC_H_ | ||||||
|  | #define CEF_LIBCEF_DLL_CPPTOC_PERMISSION_PROMPT_CALLBACK_CPPTOC_H_ | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #if !defined(BUILDING_CEF_SHARED) | ||||||
|  | #error This file can be included DLL-side only | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "include/capi/cef_permission_handler_capi.h" | ||||||
|  | #include "include/cef_permission_handler.h" | ||||||
|  | #include "libcef_dll/cpptoc/cpptoc_ref_counted.h" | ||||||
|  |  | ||||||
|  | // Wrap a C++ class with a C structure. | ||||||
|  | // This class may be instantiated and accessed DLL-side only. | ||||||
|  | class CefPermissionPromptCallbackCppToC | ||||||
|  |     : public CefCppToCRefCounted<CefPermissionPromptCallbackCppToC, | ||||||
|  |                                  CefPermissionPromptCallback, | ||||||
|  |                                  cef_permission_prompt_callback_t> { | ||||||
|  |  public: | ||||||
|  |   CefPermissionPromptCallbackCppToC(); | ||||||
|  |   virtual ~CefPermissionPromptCallbackCppToC(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif  // CEF_LIBCEF_DLL_CPPTOC_PERMISSION_PROMPT_CALLBACK_CPPTOC_H_ | ||||||
| @@ -9,13 +9,14 @@ | |||||||
| // implementations. See the translator.README.txt file in the tools directory | // implementations. See the translator.README.txt file in the tools directory | ||||||
| // for more information. | // for more information. | ||||||
| // | // | ||||||
| // $hash=f9073ac6e5a3634a3bf3c919ac1b0a9c607b4398$ | // $hash=d7ce736678ba0f43fa3f556d22b8afa2409221fb$ | ||||||
| // | // | ||||||
|  |  | ||||||
| #include "libcef_dll/ctocpp/permission_handler_ctocpp.h" | #include "libcef_dll/ctocpp/permission_handler_ctocpp.h" | ||||||
| #include "libcef_dll/cpptoc/browser_cpptoc.h" | #include "libcef_dll/cpptoc/browser_cpptoc.h" | ||||||
| #include "libcef_dll/cpptoc/frame_cpptoc.h" | #include "libcef_dll/cpptoc/frame_cpptoc.h" | ||||||
| #include "libcef_dll/cpptoc/media_access_callback_cpptoc.h" | #include "libcef_dll/cpptoc/media_access_callback_cpptoc.h" | ||||||
|  | #include "libcef_dll/cpptoc/permission_prompt_callback_cpptoc.h" | ||||||
| #include "libcef_dll/shutdown_checker.h" | #include "libcef_dll/shutdown_checker.h" | ||||||
|  |  | ||||||
| // VIRTUAL METHODS - Body may be edited by hand. | // VIRTUAL METHODS - Body may be edited by hand. | ||||||
| @@ -24,7 +25,7 @@ NO_SANITIZE("cfi-icall") | |||||||
| bool CefPermissionHandlerCToCpp::OnRequestMediaAccessPermission( | bool CefPermissionHandlerCToCpp::OnRequestMediaAccessPermission( | ||||||
|     CefRefPtr<CefBrowser> browser, |     CefRefPtr<CefBrowser> browser, | ||||||
|     CefRefPtr<CefFrame> frame, |     CefRefPtr<CefFrame> frame, | ||||||
|     const CefString& requesting_url, |     const CefString& requesting_origin, | ||||||
|     uint32 requested_permissions, |     uint32 requested_permissions, | ||||||
|     CefRefPtr<CefMediaAccessCallback> callback) { |     CefRefPtr<CefMediaAccessCallback> callback) { | ||||||
|   shutdown_checker::AssertNotShutdown(); |   shutdown_checker::AssertNotShutdown(); | ||||||
| @@ -43,9 +44,9 @@ bool CefPermissionHandlerCToCpp::OnRequestMediaAccessPermission( | |||||||
|   DCHECK(frame.get()); |   DCHECK(frame.get()); | ||||||
|   if (!frame.get()) |   if (!frame.get()) | ||||||
|     return false; |     return false; | ||||||
|   // Verify param: requesting_url; type: string_byref_const |   // Verify param: requesting_origin; type: string_byref_const | ||||||
|   DCHECK(!requesting_url.empty()); |   DCHECK(!requesting_origin.empty()); | ||||||
|   if (requesting_url.empty()) |   if (requesting_origin.empty()) | ||||||
|     return false; |     return false; | ||||||
|   // Verify param: callback; type: refptr_diff |   // Verify param: callback; type: refptr_diff | ||||||
|   DCHECK(callback.get()); |   DCHECK(callback.get()); | ||||||
| @@ -55,13 +56,74 @@ bool CefPermissionHandlerCToCpp::OnRequestMediaAccessPermission( | |||||||
|   // Execute |   // Execute | ||||||
|   int _retval = _struct->on_request_media_access_permission( |   int _retval = _struct->on_request_media_access_permission( | ||||||
|       _struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame), |       _struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame), | ||||||
|       requesting_url.GetStruct(), requested_permissions, |       requesting_origin.GetStruct(), requested_permissions, | ||||||
|       CefMediaAccessCallbackCppToC::Wrap(callback)); |       CefMediaAccessCallbackCppToC::Wrap(callback)); | ||||||
|  |  | ||||||
|   // Return type: bool |   // Return type: bool | ||||||
|   return _retval ? true : false; |   return _retval ? true : false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | NO_SANITIZE("cfi-icall") | ||||||
|  | bool CefPermissionHandlerCToCpp::OnShowPermissionPrompt( | ||||||
|  |     CefRefPtr<CefBrowser> browser, | ||||||
|  |     uint64 prompt_id, | ||||||
|  |     const CefString& requesting_origin, | ||||||
|  |     uint32 requested_permissions, | ||||||
|  |     CefRefPtr<CefPermissionPromptCallback> callback) { | ||||||
|  |   shutdown_checker::AssertNotShutdown(); | ||||||
|  |  | ||||||
|  |   cef_permission_handler_t* _struct = GetStruct(); | ||||||
|  |   if (CEF_MEMBER_MISSING(_struct, on_show_permission_prompt)) | ||||||
|  |     return false; | ||||||
|  |  | ||||||
|  |   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING | ||||||
|  |  | ||||||
|  |   // Verify param: browser; type: refptr_diff | ||||||
|  |   DCHECK(browser.get()); | ||||||
|  |   if (!browser.get()) | ||||||
|  |     return false; | ||||||
|  |   // Verify param: requesting_origin; type: string_byref_const | ||||||
|  |   DCHECK(!requesting_origin.empty()); | ||||||
|  |   if (requesting_origin.empty()) | ||||||
|  |     return false; | ||||||
|  |   // Verify param: callback; type: refptr_diff | ||||||
|  |   DCHECK(callback.get()); | ||||||
|  |   if (!callback.get()) | ||||||
|  |     return false; | ||||||
|  |  | ||||||
|  |   // Execute | ||||||
|  |   int _retval = _struct->on_show_permission_prompt( | ||||||
|  |       _struct, CefBrowserCppToC::Wrap(browser), prompt_id, | ||||||
|  |       requesting_origin.GetStruct(), requested_permissions, | ||||||
|  |       CefPermissionPromptCallbackCppToC::Wrap(callback)); | ||||||
|  |  | ||||||
|  |   // Return type: bool | ||||||
|  |   return _retval ? true : false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NO_SANITIZE("cfi-icall") | ||||||
|  | void CefPermissionHandlerCToCpp::OnDismissPermissionPrompt( | ||||||
|  |     CefRefPtr<CefBrowser> browser, | ||||||
|  |     uint64 prompt_id, | ||||||
|  |     cef_permission_request_result_t result) { | ||||||
|  |   shutdown_checker::AssertNotShutdown(); | ||||||
|  |  | ||||||
|  |   cef_permission_handler_t* _struct = GetStruct(); | ||||||
|  |   if (CEF_MEMBER_MISSING(_struct, on_dismiss_permission_prompt)) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING | ||||||
|  |  | ||||||
|  |   // Verify param: browser; type: refptr_diff | ||||||
|  |   DCHECK(browser.get()); | ||||||
|  |   if (!browser.get()) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   // Execute | ||||||
|  |   _struct->on_dismiss_permission_prompt( | ||||||
|  |       _struct, CefBrowserCppToC::Wrap(browser), prompt_id, result); | ||||||
|  | } | ||||||
|  |  | ||||||
| // CONSTRUCTOR - Do not edit by hand. | // CONSTRUCTOR - Do not edit by hand. | ||||||
|  |  | ||||||
| CefPermissionHandlerCToCpp::CefPermissionHandlerCToCpp() {} | CefPermissionHandlerCToCpp::CefPermissionHandlerCToCpp() {} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // implementations. See the translator.README.txt file in the tools directory | // implementations. See the translator.README.txt file in the tools directory | ||||||
| // for more information. | // for more information. | ||||||
| // | // | ||||||
| // $hash=1c8392555b99119b866989c5461ad48a0ac662b5$ | // $hash=5a55c2f36920a4ab385570e9be0f146d99477edb$ | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef CEF_LIBCEF_DLL_CTOCPP_PERMISSION_HANDLER_CTOCPP_H_ | #ifndef CEF_LIBCEF_DLL_CTOCPP_PERMISSION_HANDLER_CTOCPP_H_ | ||||||
| @@ -38,9 +38,19 @@ class CefPermissionHandlerCToCpp | |||||||
|   bool OnRequestMediaAccessPermission( |   bool OnRequestMediaAccessPermission( | ||||||
|       CefRefPtr<CefBrowser> browser, |       CefRefPtr<CefBrowser> browser, | ||||||
|       CefRefPtr<CefFrame> frame, |       CefRefPtr<CefFrame> frame, | ||||||
|       const CefString& requesting_url, |       const CefString& requesting_origin, | ||||||
|       uint32 requested_permissions, |       uint32 requested_permissions, | ||||||
|       CefRefPtr<CefMediaAccessCallback> callback) override; |       CefRefPtr<CefMediaAccessCallback> callback) override; | ||||||
|  |   bool OnShowPermissionPrompt( | ||||||
|  |       CefRefPtr<CefBrowser> browser, | ||||||
|  |       uint64 prompt_id, | ||||||
|  |       const CefString& requesting_origin, | ||||||
|  |       uint32 requested_permissions, | ||||||
|  |       CefRefPtr<CefPermissionPromptCallback> callback) override; | ||||||
|  |   void OnDismissPermissionPrompt( | ||||||
|  |       CefRefPtr<CefBrowser> browser, | ||||||
|  |       uint64 prompt_id, | ||||||
|  |       cef_permission_request_result_t result) override; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  // CEF_LIBCEF_DLL_CTOCPP_PERMISSION_HANDLER_CTOCPP_H_ | #endif  // CEF_LIBCEF_DLL_CTOCPP_PERMISSION_HANDLER_CTOCPP_H_ | ||||||
|   | |||||||
							
								
								
									
										60
									
								
								libcef_dll/ctocpp/permission_prompt_callback_ctocpp.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								libcef_dll/ctocpp/permission_prompt_callback_ctocpp.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | // Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights | ||||||
|  | // reserved. Use of this source code is governed by a BSD-style license that | ||||||
|  | // can be found in the LICENSE file. | ||||||
|  | // | ||||||
|  | // --------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // This file was generated by the CEF translator tool. If making changes by | ||||||
|  | // hand only do so within the body of existing method and function | ||||||
|  | // implementations. See the translator.README.txt file in the tools directory | ||||||
|  | // for more information. | ||||||
|  | // | ||||||
|  | // $hash=b149d327d3972d670f974dc92900acfbdfffff87$ | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "libcef_dll/ctocpp/permission_prompt_callback_ctocpp.h" | ||||||
|  | #include "libcef_dll/shutdown_checker.h" | ||||||
|  |  | ||||||
|  | // VIRTUAL METHODS - Body may be edited by hand. | ||||||
|  |  | ||||||
|  | NO_SANITIZE("cfi-icall") | ||||||
|  | void CefPermissionPromptCallbackCToCpp::Continue( | ||||||
|  |     cef_permission_request_result_t result) { | ||||||
|  |   shutdown_checker::AssertNotShutdown(); | ||||||
|  |  | ||||||
|  |   cef_permission_prompt_callback_t* _struct = GetStruct(); | ||||||
|  |   if (CEF_MEMBER_MISSING(_struct, cont)) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING | ||||||
|  |  | ||||||
|  |   // Execute | ||||||
|  |   _struct->cont(_struct, result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CONSTRUCTOR - Do not edit by hand. | ||||||
|  |  | ||||||
|  | CefPermissionPromptCallbackCToCpp::CefPermissionPromptCallbackCToCpp() {} | ||||||
|  |  | ||||||
|  | // DESTRUCTOR - Do not edit by hand. | ||||||
|  |  | ||||||
|  | CefPermissionPromptCallbackCToCpp::~CefPermissionPromptCallbackCToCpp() { | ||||||
|  |   shutdown_checker::AssertNotShutdown(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <> | ||||||
|  | cef_permission_prompt_callback_t* | ||||||
|  | CefCToCppRefCounted<CefPermissionPromptCallbackCToCpp, | ||||||
|  |                     CefPermissionPromptCallback, | ||||||
|  |                     cef_permission_prompt_callback_t>:: | ||||||
|  |     UnwrapDerived(CefWrapperType type, CefPermissionPromptCallback* c) { | ||||||
|  |   NOTREACHED() << "Unexpected class type: " << type; | ||||||
|  |   return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <> | ||||||
|  | CefWrapperType | ||||||
|  |     CefCToCppRefCounted<CefPermissionPromptCallbackCToCpp, | ||||||
|  |                         CefPermissionPromptCallback, | ||||||
|  |                         cef_permission_prompt_callback_t>::kWrapperType = | ||||||
|  |         WT_PERMISSION_PROMPT_CALLBACK; | ||||||
							
								
								
									
										41
									
								
								libcef_dll/ctocpp/permission_prompt_callback_ctocpp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								libcef_dll/ctocpp/permission_prompt_callback_ctocpp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | // Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights | ||||||
|  | // reserved. Use of this source code is governed by a BSD-style license that | ||||||
|  | // can be found in the LICENSE file. | ||||||
|  | // | ||||||
|  | // --------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // This file was generated by the CEF translator tool. If making changes by | ||||||
|  | // hand only do so within the body of existing method and function | ||||||
|  | // implementations. See the translator.README.txt file in the tools directory | ||||||
|  | // for more information. | ||||||
|  | // | ||||||
|  | // $hash=bdf5b8df2a3d5555f42982cd741ae13f3d1a67d1$ | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef CEF_LIBCEF_DLL_CTOCPP_PERMISSION_PROMPT_CALLBACK_CTOCPP_H_ | ||||||
|  | #define CEF_LIBCEF_DLL_CTOCPP_PERMISSION_PROMPT_CALLBACK_CTOCPP_H_ | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #if !defined(WRAPPING_CEF_SHARED) | ||||||
|  | #error This file can be included wrapper-side only | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "include/capi/cef_permission_handler_capi.h" | ||||||
|  | #include "include/cef_permission_handler.h" | ||||||
|  | #include "libcef_dll/ctocpp/ctocpp_ref_counted.h" | ||||||
|  |  | ||||||
|  | // Wrap a C structure with a C++ class. | ||||||
|  | // This class may be instantiated and accessed wrapper-side only. | ||||||
|  | class CefPermissionPromptCallbackCToCpp | ||||||
|  |     : public CefCToCppRefCounted<CefPermissionPromptCallbackCToCpp, | ||||||
|  |                                  CefPermissionPromptCallback, | ||||||
|  |                                  cef_permission_prompt_callback_t> { | ||||||
|  |  public: | ||||||
|  |   CefPermissionPromptCallbackCToCpp(); | ||||||
|  |   virtual ~CefPermissionPromptCallbackCToCpp(); | ||||||
|  |  | ||||||
|  |   // CefPermissionPromptCallback methods. | ||||||
|  |   void Continue(cef_permission_request_result_t result) override; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif  // CEF_LIBCEF_DLL_CTOCPP_PERMISSION_PROMPT_CALLBACK_CTOCPP_H_ | ||||||
| @@ -9,7 +9,7 @@ | |||||||
| // implementations. See the translator.README.txt file in the tools directory | // implementations. See the translator.README.txt file in the tools directory | ||||||
| // for more information. | // for more information. | ||||||
| // | // | ||||||
| // $hash=27716558f027af36498437317407384392a34b71$ | // $hash=5e9ff0d723683c16009ad0c7c697ea461b653aaf$ | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_ | #ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_ | ||||||
| @@ -97,6 +97,7 @@ enum CefWrapperType { | |||||||
|   WT_PANEL_DELEGATE, |   WT_PANEL_DELEGATE, | ||||||
|   WT_PDF_PRINT_CALLBACK, |   WT_PDF_PRINT_CALLBACK, | ||||||
|   WT_PERMISSION_HANDLER, |   WT_PERMISSION_HANDLER, | ||||||
|  |   WT_PERMISSION_PROMPT_CALLBACK, | ||||||
|   WT_POST_DATA, |   WT_POST_DATA, | ||||||
|   WT_POST_DATA_ELEMENT, |   WT_POST_DATA_ELEMENT, | ||||||
|   WT_PRINT_DIALOG_CALLBACK, |   WT_PRINT_DIALOG_CALLBACK, | ||||||
|   | |||||||
| @@ -253,6 +253,11 @@ patches = [ | |||||||
|     # https://bitbucket.org/chromiumembedded/cef/issues/2830 |     # https://bitbucket.org/chromiumembedded/cef/issues/2830 | ||||||
|     'name': 'chrome_browser_net_proxy', |     'name': 'chrome_browser_net_proxy', | ||||||
|   }, |   }, | ||||||
|  |   { | ||||||
|  |     # Support override of CreatePermissionPrompt. | ||||||
|  |     # https://bitbucket.org/chromiumembedded/cef/issues/3352 | ||||||
|  |     'name': 'chrome_browser_permission_prompt', | ||||||
|  |   }, | ||||||
|   { |   { | ||||||
|     # alloy: Don't initialize ExtensionSystemFactory when extensions are |     # alloy: Don't initialize ExtensionSystemFactory when extensions are | ||||||
|     # disabled. |     # disabled. | ||||||
|   | |||||||
							
								
								
									
										73
									
								
								patch/patches/chrome_browser_permission_prompt.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								patch/patches/chrome_browser_permission_prompt.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | diff --git chrome/browser/permissions/chrome_permissions_client.cc chrome/browser/permissions/chrome_permissions_client.cc | ||||||
|  | index 894a7424580ac..fa78c8dabbdd2 100644 | ||||||
|  | --- chrome/browser/permissions/chrome_permissions_client.cc | ||||||
|  | +++ chrome/browser/permissions/chrome_permissions_client.cc | ||||||
|  | @@ -12,6 +12,7 @@ | ||||||
|  |  #include "base/strings/string_util.h" | ||||||
|  |  #include "build/build_config.h" | ||||||
|  |  #include "build/chromeos_buildflags.h" | ||||||
|  | +#include "cef/libcef/features/runtime.h" | ||||||
|  |  #include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h" | ||||||
|  |  #include "chrome/browser/content_settings/cookie_settings_factory.h" | ||||||
|  |  #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | ||||||
|  | @@ -212,6 +213,9 @@ permissions::PermissionManager* ChromePermissionsClient::GetPermissionManager( | ||||||
|  |  double ChromePermissionsClient::GetSiteEngagementScore( | ||||||
|  |      content::BrowserContext* browser_context, | ||||||
|  |      const GURL& origin) { | ||||||
|  | +  // No SiteEngagementService with the Alloy runtime. | ||||||
|  | +  if (cef::IsAlloyRuntimeEnabled()) | ||||||
|  | +    return 0.0; | ||||||
|  |    return site_engagement::SiteEngagementService::Get( | ||||||
|  |               Profile::FromBrowserContext(browser_context)) | ||||||
|  |        ->GetScore(origin); | ||||||
|  | diff --git chrome/browser/ui/permission_bubble/permission_prompt.h chrome/browser/ui/permission_bubble/permission_prompt.h | ||||||
|  | index c2836d15eba30..0c03c2b4666a6 100644 | ||||||
|  | --- chrome/browser/ui/permission_bubble/permission_prompt.h | ||||||
|  | +++ chrome/browser/ui/permission_bubble/permission_prompt.h | ||||||
|  | @@ -11,6 +11,13 @@ namespace content { | ||||||
|  |  class WebContents; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +using CreatePermissionPromptFunctionPtr = | ||||||
|  | +    std::unique_ptr<permissions::PermissionPrompt> (*)( | ||||||
|  | +        content::WebContents* web_contents, | ||||||
|  | +        permissions::PermissionPrompt::Delegate* delegate, | ||||||
|  | +        bool* default_handling); | ||||||
|  | +void SetCreatePermissionPromptFunction(CreatePermissionPromptFunctionPtr); | ||||||
|  | + | ||||||
|  |  // Factory function to create permission prompts for chrome. | ||||||
|  |  std::unique_ptr<permissions::PermissionPrompt> CreatePermissionPrompt( | ||||||
|  |      content::WebContents* web_contents, | ||||||
|  | diff --git chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc | ||||||
|  | index 70e37336a5001..a2df1bd28c994 100644 | ||||||
|  | --- chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc | ||||||
|  | +++ chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc | ||||||
|  | @@ -100,11 +100,28 @@ bool ShouldBubbleStartOpen(permissions::PermissionPrompt::Delegate* delegate) { | ||||||
|  |    return false; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +CreatePermissionPromptFunctionPtr g_create_permission_prompt_ptr = nullptr; | ||||||
|  | + | ||||||
|  |  }  // namespace | ||||||
|  |   | ||||||
|  | +void SetCreatePermissionPromptFunction( | ||||||
|  | +    CreatePermissionPromptFunctionPtr ptr) { | ||||||
|  | +  g_create_permission_prompt_ptr = ptr; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  std::unique_ptr<permissions::PermissionPrompt> CreatePermissionPrompt( | ||||||
|  |      content::WebContents* web_contents, | ||||||
|  |      permissions::PermissionPrompt::Delegate* delegate) { | ||||||
|  | +  if (g_create_permission_prompt_ptr) { | ||||||
|  | +    bool default_handling = true; | ||||||
|  | +    auto prompt = g_create_permission_prompt_ptr(web_contents, delegate, | ||||||
|  | +                                                 &default_handling); | ||||||
|  | +    if (prompt) | ||||||
|  | +      return prompt; | ||||||
|  | +    if (!default_handling) | ||||||
|  | +      return nullptr; | ||||||
|  | +  } | ||||||
|  | + | ||||||
|  |    Browser* browser = chrome::FindBrowserWithWebContents(web_contents); | ||||||
|  |    if (!browser) { | ||||||
|  |      DLOG(WARNING) << "Permission prompt suppressed because the WebContents is " | ||||||
| @@ -864,7 +864,7 @@ void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser, | |||||||
| bool ClientHandler::OnRequestMediaAccessPermission( | bool ClientHandler::OnRequestMediaAccessPermission( | ||||||
|     CefRefPtr<CefBrowser> browser, |     CefRefPtr<CefBrowser> browser, | ||||||
|     CefRefPtr<CefFrame> frame, |     CefRefPtr<CefFrame> frame, | ||||||
|     const CefString& requesting_url, |     const CefString& requesting_origin, | ||||||
|     uint32 requested_permissions, |     uint32 requested_permissions, | ||||||
|     CefRefPtr<CefMediaAccessCallback> callback) { |     CefRefPtr<CefMediaAccessCallback> callback) { | ||||||
|   callback->Continue(media_handling_disabled_ ? CEF_MEDIA_PERMISSION_NONE |   callback->Continue(media_handling_disabled_ ? CEF_MEDIA_PERMISSION_NONE | ||||||
|   | |||||||
| @@ -237,7 +237,7 @@ class ClientHandler : public CefClient, | |||||||
|   bool OnRequestMediaAccessPermission( |   bool OnRequestMediaAccessPermission( | ||||||
|       CefRefPtr<CefBrowser> browser, |       CefRefPtr<CefBrowser> browser, | ||||||
|       CefRefPtr<CefFrame> frame, |       CefRefPtr<CefFrame> frame, | ||||||
|       const CefString& requesting_url, |       const CefString& requesting_origin, | ||||||
|       uint32 requested_permissions, |       uint32 requested_permissions, | ||||||
|       CefRefPtr<CefMediaAccessCallback> callback) override; |       CefRefPtr<CefMediaAccessCallback> callback) override; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ namespace { | |||||||
|  |  | ||||||
| // Media access requires HTTPS. | // Media access requires HTTPS. | ||||||
| const char kMediaUrl[] = "https://media-access-test/media.html"; | const char kMediaUrl[] = "https://media-access-test/media.html"; | ||||||
|  | const char kMediaOrigin[] = "https://media-access-test/"; | ||||||
|  |  | ||||||
| // Browser-side app delegate. | // Browser-side app delegate. | ||||||
| class MediaAccessBrowserTest : public client::ClientAppBrowser::Delegate, | class MediaAccessBrowserTest : public client::ClientAppBrowser::Delegate, | ||||||
| @@ -46,6 +47,7 @@ class TestSetup { | |||||||
|   bool deny_implicitly = false; |   bool deny_implicitly = false; | ||||||
|   bool continue_async = false; |   bool continue_async = false; | ||||||
|  |  | ||||||
|  |   TrackCallback got_request; | ||||||
|   TrackCallback got_success; |   TrackCallback got_success; | ||||||
|   TrackCallback got_audio; |   TrackCallback got_audio; | ||||||
|   TrackCallback got_video; |   TrackCallback got_video; | ||||||
| @@ -64,10 +66,10 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler { | |||||||
|       CefRefPtr<CefCallback> callback) override { |       CefRefPtr<CefCallback> callback) override { | ||||||
|     std::string newUrl = request->GetURL(); |     std::string newUrl = request->GetURL(); | ||||||
|     if (newUrl.find("tests/exit") != std::string::npos) { |     if (newUrl.find("tests/exit") != std::string::npos) { | ||||||
|       CefURLParts url_parts; |  | ||||||
|       CefParseURL(newUrl, url_parts); |  | ||||||
|       if (newUrl.find("SUCCESS") != std::string::npos) { |       if (newUrl.find("SUCCESS") != std::string::npos) { | ||||||
|  |         EXPECT_FALSE(test_setup_->got_success); | ||||||
|         test_setup_->got_success.yes(); |         test_setup_->got_success.yes(); | ||||||
|  |  | ||||||
|         std::string data_string = newUrl.substr(newUrl.find("&data=") + |         std::string data_string = newUrl.substr(newUrl.find("&data=") + | ||||||
|                                                 std::string("&data=").length()); |                                                 std::string("&data=").length()); | ||||||
|         std::string data_string_decoded = CefURIDecode( |         std::string data_string_decoded = CefURIDecode( | ||||||
| @@ -122,7 +124,7 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler { | |||||||
|         "> 0, got_video_track: stream.getVideoTracks().length > 0});" |         "> 0, got_video_track: stream.getVideoTracks().length > 0});" | ||||||
|         "})" |         "})" | ||||||
|         ".catch(function(err) {" |         ".catch(function(err) {" | ||||||
|         "console.log(err);" |         "console.log(err.toString());" | ||||||
|         "onResult(`FAILURE`);" |         "onResult(`FAILURE`);" | ||||||
|         "});" |         "});" | ||||||
|         "</script>" |         "</script>" | ||||||
| @@ -146,31 +148,25 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler { | |||||||
|     return this; |     return this; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void CompleteTest() { |  | ||||||
|     if (!CefCurrentlyOn(TID_UI)) { |  | ||||||
|       CefPostTask(TID_UI, |  | ||||||
|                   base::BindOnce(&MediaAccessTestHandler::CompleteTest, this)); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     DestroyTest(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   bool OnRequestMediaAccessPermission( |   bool OnRequestMediaAccessPermission( | ||||||
|       CefRefPtr<CefBrowser> browser, |       CefRefPtr<CefBrowser> browser, | ||||||
|       CefRefPtr<CefFrame> frame, |       CefRefPtr<CefFrame> frame, | ||||||
|       const CefString& requesting_url, |       const CefString& requesting_origin, | ||||||
|       uint32 requested_permissions, |       uint32 requested_permissions, | ||||||
|       CefRefPtr<CefMediaAccessCallback> callback) override { |       CefRefPtr<CefMediaAccessCallback> callback) override { | ||||||
|     EXPECT_UI_THREAD(); |     EXPECT_UI_THREAD(); | ||||||
|     EXPECT_TRUE(frame->IsMain()); |     EXPECT_TRUE(frame->IsMain()); | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(requested_permissions, request_); | ||||||
|  |     EXPECT_STREQ(kMediaOrigin, requesting_origin.ToString().c_str()); | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(test_setup_->got_request); | ||||||
|  |     test_setup_->got_request.yes(); | ||||||
|  |  | ||||||
|     if (test_setup_->deny_implicitly) { |     if (test_setup_->deny_implicitly) { | ||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     EXPECT_EQ(requested_permissions, request_); |  | ||||||
|  |  | ||||||
|     if (test_setup_->continue_async) { |     if (test_setup_->continue_async) { | ||||||
|       CefPostTask(TID_UI, base::BindOnce(&CefMediaAccessCallback::Continue, |       CefPostTask(TID_UI, base::BindOnce(&CefMediaAccessCallback::Continue, | ||||||
|                                          callback, response_)); |                                          callback, response_)); | ||||||
| @@ -238,6 +234,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningFalse) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -255,6 +252,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningNoPermission) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -273,6 +271,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningNoPermissionAsync) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -288,6 +287,7 @@ TEST(MediaAccessTest, DeviceFailureWhenRequestingAudioButReturningVideo) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -303,6 +303,7 @@ TEST(MediaAccessTest, DeviceFailureWhenRequestingVideoButReturningAudio) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -320,6 +321,7 @@ TEST(MediaAccessTest, DevicePartialFailureReturningVideo) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -337,6 +339,7 @@ TEST(MediaAccessTest, DevicePartialFailureReturningAudio) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -354,6 +357,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture1) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -371,6 +375,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture2) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -386,6 +391,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture3) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -401,6 +407,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture4) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -416,6 +423,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture5) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -431,6 +439,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture6) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -446,6 +455,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioOnly) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_TRUE(test_setup.got_success); |   EXPECT_TRUE(test_setup.got_success); | ||||||
|   EXPECT_TRUE(test_setup.got_audio); |   EXPECT_TRUE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -461,6 +471,7 @@ TEST(MediaAccessTest, DeviceSuccessVideoOnly) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_TRUE(test_setup.got_success); |   EXPECT_TRUE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_TRUE(test_setup.got_video); |   EXPECT_TRUE(test_setup.got_video); | ||||||
| @@ -479,6 +490,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioVideo) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_TRUE(test_setup.got_success); |   EXPECT_TRUE(test_setup.got_success); | ||||||
|   EXPECT_TRUE(test_setup.got_audio); |   EXPECT_TRUE(test_setup.got_audio); | ||||||
|   EXPECT_TRUE(test_setup.got_video); |   EXPECT_TRUE(test_setup.got_video); | ||||||
| @@ -498,6 +510,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioVideoAsync) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_TRUE(test_setup.got_success); |   EXPECT_TRUE(test_setup.got_success); | ||||||
|   EXPECT_TRUE(test_setup.got_audio); |   EXPECT_TRUE(test_setup.got_audio); | ||||||
|   EXPECT_TRUE(test_setup.got_video); |   EXPECT_TRUE(test_setup.got_video); | ||||||
| @@ -516,6 +529,7 @@ TEST(MediaAccessTest, DesktopFailureWhenReturningNoPermission) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -531,6 +545,7 @@ TEST(MediaAccessTest, DesktopFailureWhenRequestingVideoButReturningAudio) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
| @@ -548,6 +563,7 @@ TEST(MediaAccessTest, DesktopPartialSuccessReturningVideo) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_TRUE(test_setup.got_success); |   EXPECT_TRUE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_TRUE(test_setup.got_video); |   EXPECT_TRUE(test_setup.got_video); | ||||||
| @@ -564,6 +580,7 @@ TEST(MediaAccessTest, DesktopPartialFailureReturningAudio) { | |||||||
|   handler->ExecuteTest(); |   handler->ExecuteTest(); | ||||||
|   ReleaseAndWaitForDestructor(handler); |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_request); | ||||||
|   EXPECT_FALSE(test_setup.got_success); |   EXPECT_FALSE(test_setup.got_success); | ||||||
|   EXPECT_FALSE(test_setup.got_audio); |   EXPECT_FALSE(test_setup.got_audio); | ||||||
|   EXPECT_FALSE(test_setup.got_video); |   EXPECT_FALSE(test_setup.got_video); | ||||||
|   | |||||||
							
								
								
									
										493
									
								
								tests/ceftests/permission_prompt_unittest.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										493
									
								
								tests/ceftests/permission_prompt_unittest.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,493 @@ | |||||||
|  | // Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style license that can be found | ||||||
|  | // in the LICENSE file. | ||||||
|  |  | ||||||
|  | #include <string> | ||||||
|  | #include <vector> | ||||||
|  |  | ||||||
|  | #include "include/base/cef_bind.h" | ||||||
|  | #include "include/cef_parser.h" | ||||||
|  | #include "include/cef_permission_handler.h" | ||||||
|  | #include "include/cef_request_context_handler.h" | ||||||
|  | #include "include/wrapper/cef_closure_task.h" | ||||||
|  | #include "include/wrapper/cef_stream_resource_handler.h" | ||||||
|  | #include "tests/ceftests/test_handler.h" | ||||||
|  | #include "tests/ceftests/test_suite.h" | ||||||
|  | #include "tests/gtest/include/gtest/gtest.h" | ||||||
|  | #include "tests/shared/browser/client_app_browser.h" | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  |  | ||||||
|  | // Most permissions require HTTPS. | ||||||
|  | constexpr char kPromptUrl[] = "https://permission-prompt-test/prompt.html"; | ||||||
|  | constexpr char kPromptOrigin[] = "https://permission-prompt-test/"; | ||||||
|  |  | ||||||
|  | constexpr char kPromptNavUrl[] = "https://permission-prompt-test/nav.html"; | ||||||
|  |  | ||||||
|  | class TestSetup { | ||||||
|  |  public: | ||||||
|  |   TestSetup() {} | ||||||
|  |  | ||||||
|  |   // CONFIGURATION | ||||||
|  |  | ||||||
|  |   // Deny the prompt by returning false in OnShowPermissionPrompt. | ||||||
|  |   bool deny_implicitly = false; | ||||||
|  |  | ||||||
|  |   // Deny the prompt (implicitly) by not triggering it via a user gesture to | ||||||
|  |   // begin with. | ||||||
|  |   bool deny_no_gesture = false; | ||||||
|  |  | ||||||
|  |   // Deny the prompt by returning true in OnShowPermissionPrompt but then never | ||||||
|  |   // calling CefPermissionPromptCallback::Continue. | ||||||
|  |   bool deny_with_navigation = false; | ||||||
|  |  | ||||||
|  |   // Don't synchronously execute the callback in OnShowPermissionPrompt. | ||||||
|  |   bool continue_async = false; | ||||||
|  |  | ||||||
|  |   // RESULTS | ||||||
|  |  | ||||||
|  |   // Method callbacks. | ||||||
|  |   TrackCallback got_prompt; | ||||||
|  |   TrackCallback got_dismiss; | ||||||
|  |  | ||||||
|  |   // JS success state. | ||||||
|  |   TrackCallback got_js_success; | ||||||
|  |   TrackCallback got_js_success_data; | ||||||
|  |  | ||||||
|  |   // JS error state. | ||||||
|  |   TrackCallback got_js_error; | ||||||
|  |   std::string js_error_str; | ||||||
|  |  | ||||||
|  |   // JS timeout state. | ||||||
|  |   TrackCallback got_js_timeout; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class PermissionPromptTestHandler : public TestHandler, | ||||||
|  |                                     public CefPermissionHandler { | ||||||
|  |  public: | ||||||
|  |   PermissionPromptTestHandler(TestSetup* tr, | ||||||
|  |                               uint32 request, | ||||||
|  |                               cef_permission_request_result_t result) | ||||||
|  |       : test_setup_(tr), request_(request), result_(result) {} | ||||||
|  |  | ||||||
|  |   cef_return_value_t OnBeforeResourceLoad( | ||||||
|  |       CefRefPtr<CefBrowser> browser, | ||||||
|  |       CefRefPtr<CefFrame> frame, | ||||||
|  |       CefRefPtr<CefRequest> request, | ||||||
|  |       CefRefPtr<CefCallback> callback) override { | ||||||
|  |     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_js_success); | ||||||
|  |         test_setup_->got_js_success.yes(); | ||||||
|  |  | ||||||
|  |         auto dict = ParseURLData(newUrl); | ||||||
|  |         if (dict->GetBool("got_data")) { | ||||||
|  |           test_setup_->got_js_success_data.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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return RV_CONTINUE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void RunTest() override { | ||||||
|  |     std::string page = | ||||||
|  |         "<html><head>" | ||||||
|  |         "<script>" | ||||||
|  |         "function onResult(val, data) {" | ||||||
|  |         " if(!data) {" | ||||||
|  |         "   data = {};" | ||||||
|  |         " }" | ||||||
|  |         " document.location = " | ||||||
|  |         "`http://tests/" | ||||||
|  |         "exit?result=${val}&data=${encodeURIComponent(JSON.stringify(data))}`;" | ||||||
|  |         "}" | ||||||
|  |         "function makeRequest() {"; | ||||||
|  |  | ||||||
|  |     if (request_ == CEF_PERMISSION_TYPE_WINDOW_PLACEMENT) { | ||||||
|  |       page += | ||||||
|  |           "  window.getScreenDetails().then(function(details) {" | ||||||
|  |           "    onResult(`SUCCESS`, {got_data: details.screens.length > 0});" | ||||||
|  |           "  })"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     page += | ||||||
|  |         "  .catch(function(err) {" | ||||||
|  |         "    console.log(err.toString());" | ||||||
|  |         "    onResult(`ERROR`, {error_str: err.toString()});" | ||||||
|  |         "  });"; | ||||||
|  |  | ||||||
|  |     if (test_setup_->deny_implicitly) { | ||||||
|  |       // Implicit IGNORE result means the promise will never resolve, so add a | ||||||
|  |       // timeout. | ||||||
|  |       page += "  setTimeout(() => { onResult(`TIMEOUT`); }, 1000);"; | ||||||
|  |     } else if (test_setup_->deny_with_navigation) { | ||||||
|  |       // Cancel the pending permission request by navigating. | ||||||
|  |       page += "  setTimeout(() => { document.location = '" + | ||||||
|  |               std::string(kPromptNavUrl) + "'; }, 1000);"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     page += | ||||||
|  |         "}" | ||||||
|  |         "</script>" | ||||||
|  |         "</head><body>"; | ||||||
|  |  | ||||||
|  |     if (test_setup_->deny_no_gesture) { | ||||||
|  |       // Expect this request to be blocked. See comments on OnLoadEnd. | ||||||
|  |       page += "<script>makeRequest();</script>"; | ||||||
|  |     } else { | ||||||
|  |       page += "<a href='#' onclick='makeRequest(); return false;'>CLICK ME</a>"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     page += "</body></html>"; | ||||||
|  |  | ||||||
|  |     // Create the request context that will use an in-memory cache. | ||||||
|  |     CefRequestContextSettings settings; | ||||||
|  |     CefRefPtr<CefRequestContext> request_context = | ||||||
|  |         CefRequestContext::CreateContext(settings, nullptr); | ||||||
|  |  | ||||||
|  |     AddResource(kPromptUrl, page, "text/html"); | ||||||
|  |  | ||||||
|  |     if (test_setup_->deny_with_navigation) { | ||||||
|  |       AddResource(kPromptNavUrl, "<html><body>Navigated</body></html>", | ||||||
|  |                   "text/html"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Create the browser. | ||||||
|  |     CreateBrowser(kPromptUrl, request_context); | ||||||
|  |  | ||||||
|  |     // Time out the test after a reasonable period of time. | ||||||
|  |     SetTestTimeout(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   CefRefPtr<CefPermissionHandler> GetPermissionHandler() override { | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void OnLoadEnd(CefRefPtr<CefBrowser> browser, | ||||||
|  |                  CefRefPtr<CefFrame> frame, | ||||||
|  |                  int httpStatusCode) override { | ||||||
|  |     if (test_setup_->deny_no_gesture) | ||||||
|  |       return; | ||||||
|  |  | ||||||
|  |     if (test_setup_->deny_with_navigation) { | ||||||
|  |       if (frame->GetURL().ToString() == kPromptNavUrl) { | ||||||
|  |         DestroyTest(); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Begin the permissions request by clicking a link. This is necessary | ||||||
|  |     // because some prompts may be blocked without a transient user activation | ||||||
|  |     // (HasTransientUserActivation returning true in Chromium). | ||||||
|  |     SendClick(browser); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   bool OnShowPermissionPrompt( | ||||||
|  |       CefRefPtr<CefBrowser> browser, | ||||||
|  |       uint64 prompt_id, | ||||||
|  |       const CefString& requesting_origin, | ||||||
|  |       uint32 requested_permissions, | ||||||
|  |       CefRefPtr<CefPermissionPromptCallback> callback) override { | ||||||
|  |     EXPECT_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     prompt_id_ = prompt_id; | ||||||
|  |     EXPECT_GT(prompt_id, 0U); | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(request_, requested_permissions); | ||||||
|  |     EXPECT_STREQ(kPromptOrigin, requesting_origin.ToString().c_str()); | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(test_setup_->got_prompt); | ||||||
|  |     test_setup_->got_prompt.yes(); | ||||||
|  |  | ||||||
|  |     if (test_setup_->deny_implicitly) { | ||||||
|  |       // Causes implicit IGNORE result for the permission request. | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (test_setup_->deny_with_navigation) { | ||||||
|  |       // Handle the permission request, but never execute the callback. | ||||||
|  |       return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (test_setup_->continue_async) { | ||||||
|  |       CefPostTask(TID_UI, base::BindOnce(&CefPermissionPromptCallback::Continue, | ||||||
|  |                                          callback, result_)); | ||||||
|  |     } else { | ||||||
|  |       callback->Continue(result_); | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void OnDismissPermissionPrompt( | ||||||
|  |       CefRefPtr<CefBrowser> browser, | ||||||
|  |       uint64 prompt_id, | ||||||
|  |       cef_permission_request_result_t result) override { | ||||||
|  |     EXPECT_UI_THREAD(); | ||||||
|  |     EXPECT_EQ(prompt_id_, prompt_id); | ||||||
|  |     EXPECT_EQ(result_, result); | ||||||
|  |     EXPECT_FALSE(test_setup_->got_dismiss); | ||||||
|  |     test_setup_->got_dismiss.yes(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void DestroyTest() override { | ||||||
|  |     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: | ||||||
|  |   void SendClick(CefRefPtr<CefBrowser> browser) { | ||||||
|  |     CefMouseEvent mouse_event; | ||||||
|  |     mouse_event.x = 20; | ||||||
|  |     mouse_event.y = 20; | ||||||
|  |  | ||||||
|  |     // Add some delay to avoid having events dropped or rate limited. | ||||||
|  |     CefPostDelayedTask( | ||||||
|  |         TID_UI, | ||||||
|  |         base::BindOnce(&CefBrowserHost::SendMouseClickEvent, browser->GetHost(), | ||||||
|  |                        mouse_event, MBT_LEFT, false, 1), | ||||||
|  |         50); | ||||||
|  |     CefPostDelayedTask( | ||||||
|  |         TID_UI, | ||||||
|  |         base::BindOnce(&CefBrowserHost::SendMouseClickEvent, browser->GetHost(), | ||||||
|  |                        mouse_event, MBT_LEFT, true, 1), | ||||||
|  |         100); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   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 cef_permission_request_result_t result_; | ||||||
|  |   uint64 prompt_id_ = 0U; | ||||||
|  |  | ||||||
|  |   IMPLEMENT_REFCOUNTING(PermissionPromptTestHandler); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace | ||||||
|  |  | ||||||
|  | // Window placement permission requests. | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementReturningFalse) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |   test_setup.deny_implicitly = true; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_IGNORE); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   // No OnDismissPermissionPrompt callback for default handling. | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_timeout); | ||||||
|  |   EXPECT_FALSE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementNoGesture) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |   test_setup.deny_no_gesture = true; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_IGNORE); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   // No OnShowPermissionPrompt or OnDismissPermissionPrompt callbacks for | ||||||
|  |   // prompts that are blocked. | ||||||
|  |   EXPECT_FALSE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_error); | ||||||
|  |   EXPECT_STREQ("NotAllowedError: Permission decision deferred.", | ||||||
|  |                test_setup.js_error_str.c_str()); | ||||||
|  |   EXPECT_FALSE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementNoContinue) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |   test_setup.deny_with_navigation = true; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_IGNORE); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   // Callbacks but no JS result. | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementResultAccept) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_ACCEPT); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_success); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_success_data); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementResultAcceptAsync) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |   test_setup.continue_async = true; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_ACCEPT); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_success); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_success_data); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementResultDeny) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_DENY); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_error); | ||||||
|  |   EXPECT_STREQ("NotAllowedError: Permission denied.", | ||||||
|  |                test_setup.js_error_str.c_str()); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementResultDenyAsync) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |   test_setup.continue_async = true; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_DENY); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_error); | ||||||
|  |   EXPECT_STREQ("NotAllowedError: Permission denied.", | ||||||
|  |                test_setup.js_error_str.c_str()); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementResultDismiss) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_DISMISS); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_error); | ||||||
|  |   EXPECT_STREQ("NotAllowedError: Permission decision deferred.", | ||||||
|  |                test_setup.js_error_str.c_str()); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementResultDismissAsync) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |   test_setup.continue_async = true; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_DISMISS); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_error); | ||||||
|  |   EXPECT_STREQ("NotAllowedError: Permission decision deferred.", | ||||||
|  |                test_setup.js_error_str.c_str()); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementResultIgnore) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_IGNORE); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_error); | ||||||
|  |   EXPECT_STREQ("NotAllowedError: Permission decision deferred.", | ||||||
|  |                test_setup.js_error_str.c_str()); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(PermissionPromptTest, WindowPlacementResultIgnoreAsync) { | ||||||
|  |   TestSetup test_setup; | ||||||
|  |   test_setup.continue_async = true; | ||||||
|  |  | ||||||
|  |   CefRefPtr<PermissionPromptTestHandler> handler = | ||||||
|  |       new PermissionPromptTestHandler(&test_setup, | ||||||
|  |                                       CEF_PERMISSION_TYPE_WINDOW_PLACEMENT, | ||||||
|  |                                       CEF_PERMISSION_RESULT_IGNORE); | ||||||
|  |   handler->ExecuteTest(); | ||||||
|  |   ReleaseAndWaitForDestructor(handler); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(test_setup.got_prompt); | ||||||
|  |   EXPECT_TRUE(test_setup.got_js_error); | ||||||
|  |   EXPECT_STREQ("NotAllowedError: Permission decision deferred.", | ||||||
|  |                test_setup.js_error_str.c_str()); | ||||||
|  |   EXPECT_TRUE(test_setup.got_dismiss); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user