Merge pull request #4223 from deepak1556/notification_disable_patch
session: add setPermissionRequestHandler api
This commit is contained in:
		
				commit
				
					
						69f93a7528
					
				
			
		
					 21 changed files with 666 additions and 2 deletions
				
			
		|  | @ -14,8 +14,10 @@ | |||
| #include "atom/browser/api/save_page_handler.h" | ||||
| #include "atom/browser/atom_browser_context.h" | ||||
| #include "atom/browser/atom_browser_main_parts.h" | ||||
| #include "atom/browser/atom_permission_manager.h" | ||||
| #include "atom/browser/net/atom_cert_verifier.h" | ||||
| #include "atom/common/native_mate_converters/callback.h" | ||||
| #include "atom/common/native_mate_converters/content_converter.h" | ||||
| #include "atom/common/native_mate_converters/gurl_converter.h" | ||||
| #include "atom/common/native_mate_converters/file_path_converter.h" | ||||
| #include "atom/common/native_mate_converters/net_converter.h" | ||||
|  | @ -397,6 +399,18 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val, | |||
|   browser_context_->cert_verifier()->SetVerifyProc(proc); | ||||
| } | ||||
| 
 | ||||
| void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val, | ||||
|                                           mate::Arguments* args) { | ||||
|   AtomPermissionManager::RequestHandler handler; | ||||
|   if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) { | ||||
|     args->ThrowError("Must pass null or function"); | ||||
|     return; | ||||
|   } | ||||
|   auto permission_manager = static_cast<AtomPermissionManager*>( | ||||
|       browser_context()->GetPermissionManager()); | ||||
|   permission_manager->SetPermissionRequestHandler(handler); | ||||
| } | ||||
| 
 | ||||
| v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) { | ||||
|   if (cookies_.IsEmpty()) { | ||||
|     auto handle = atom::api::Cookies::Create(isolate, browser_context()); | ||||
|  | @ -448,6 +462,8 @@ void Session::BuildPrototype(v8::Isolate* isolate, | |||
|       .SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation) | ||||
|       .SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation) | ||||
|       .SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc) | ||||
|       .SetMethod("setPermissionRequestHandler", | ||||
|                  &Session::SetPermissionRequestHandler) | ||||
|       .SetProperty("cookies", &Session::Cookies) | ||||
|       .SetProperty("webRequest", &Session::WebRequest); | ||||
| } | ||||
|  |  | |||
|  | @ -76,6 +76,8 @@ class Session: public mate::TrackableObject<Session>, | |||
|   void EnableNetworkEmulation(const mate::Dictionary& options); | ||||
|   void DisableNetworkEmulation(); | ||||
|   void SetCertVerifyProc(v8::Local<v8::Value> proc, mate::Arguments* args); | ||||
|   void SetPermissionRequestHandler(v8::Local<v8::Value> val, | ||||
|                                    mate::Arguments* args); | ||||
|   v8::Local<v8::Value> Cookies(v8::Isolate* isolate); | ||||
|   v8::Local<v8::Value> WebRequest(v8::Isolate* isolate); | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ | |||
| #include "atom/browser/atom_browser_context.h" | ||||
| #include "atom/browser/atom_browser_main_parts.h" | ||||
| #include "atom/browser/native_window.h" | ||||
| #include "atom/browser/web_contents_permission_helper.h" | ||||
| #include "atom/browser/web_contents_preferences.h" | ||||
| #include "atom/browser/web_view_guest_delegate.h" | ||||
| #include "atom/common/api/api_messages.h" | ||||
|  | @ -263,6 +264,9 @@ WebContents::WebContents(v8::Isolate* isolate, | |||
|   // Save the preferences in C++.
 | ||||
|   new WebContentsPreferences(web_contents, options); | ||||
| 
 | ||||
|   // Intialize permission helper.
 | ||||
|   WebContentsPermissionHelper::CreateForWebContents(web_contents); | ||||
| 
 | ||||
|   web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); | ||||
| 
 | ||||
|   if (is_guest) { | ||||
|  | @ -387,6 +391,18 @@ void WebContents::HandleKeyboardEvent( | |||
| 
 | ||||
| void WebContents::EnterFullscreenModeForTab(content::WebContents* source, | ||||
|                                             const GURL& origin) { | ||||
|   auto permission_helper = | ||||
|       WebContentsPermissionHelper::FromWebContents(source); | ||||
|   auto callback = base::Bind(&WebContents::OnEnterFullscreenModeForTab, | ||||
|                              base::Unretained(this), source, origin); | ||||
|   permission_helper->RequestFullscreenPermission(callback); | ||||
| } | ||||
| 
 | ||||
| void WebContents::OnEnterFullscreenModeForTab(content::WebContents* source, | ||||
|                                               const GURL& origin, | ||||
|                                               bool allowed) { | ||||
|   if (!allowed) | ||||
|     return; | ||||
|   CommonWebContentsDelegate::EnterFullscreenModeForTab(source, origin); | ||||
|   Emit("enter-html-full-screen"); | ||||
| } | ||||
|  | @ -445,6 +461,24 @@ void WebContents::FindReply(content::WebContents* web_contents, | |||
|   } | ||||
| } | ||||
| 
 | ||||
| void WebContents::RequestMediaAccessPermission( | ||||
|     content::WebContents* web_contents, | ||||
|     const content::MediaStreamRequest& request, | ||||
|     const content::MediaResponseCallback& callback) { | ||||
|   auto permission_helper = | ||||
|       WebContentsPermissionHelper::FromWebContents(web_contents); | ||||
|   permission_helper->RequestMediaAccessPermission(request, callback); | ||||
| } | ||||
| 
 | ||||
| void WebContents::RequestToLockMouse( | ||||
|     content::WebContents* web_contents, | ||||
|     bool user_gesture, | ||||
|     bool last_unlocked_by_target) { | ||||
|   auto permission_helper = | ||||
|       WebContentsPermissionHelper::FromWebContents(web_contents); | ||||
|   permission_helper->RequestPointerLockPermission(user_gesture); | ||||
| } | ||||
| 
 | ||||
| void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { | ||||
|   // Do nothing, we override this method just to avoid compilation error since
 | ||||
|   // there are two virtual functions named BeforeUnloadFired.
 | ||||
|  |  | |||
|  | @ -134,6 +134,11 @@ class WebContents : public mate::TrackableObject<WebContents>, | |||
|   void SetAllowTransparency(bool allow); | ||||
|   bool IsGuest() const; | ||||
| 
 | ||||
|   // Callback triggered on permission response.
 | ||||
|   void OnEnterFullscreenModeForTab(content::WebContents* source, | ||||
|                                    const GURL& origin, | ||||
|                                    bool allowed); | ||||
| 
 | ||||
|   // Returns the web preferences of current WebContents.
 | ||||
|   v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate); | ||||
| 
 | ||||
|  | @ -196,6 +201,14 @@ class WebContents : public mate::TrackableObject<WebContents>, | |||
|                  const gfx::Rect& selection_rect, | ||||
|                  int active_match_ordinal, | ||||
|                  bool final_update) override; | ||||
|   void RequestMediaAccessPermission( | ||||
|       content::WebContents* web_contents, | ||||
|       const content::MediaStreamRequest& request, | ||||
|       const content::MediaResponseCallback& callback) override; | ||||
|   void RequestToLockMouse( | ||||
|       content::WebContents* web_contents, | ||||
|       bool user_gesture, | ||||
|       bool last_unlocked_by_target) override; | ||||
| 
 | ||||
|   // content::WebContentsObserver:
 | ||||
|   void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ | |||
| #include "atom/browser/atom_resource_dispatcher_host_delegate.h" | ||||
| #include "atom/browser/atom_speech_recognition_manager_delegate.h" | ||||
| #include "atom/browser/native_window.h" | ||||
| #include "atom/browser/web_contents_permission_helper.h" | ||||
| #include "atom/browser/web_contents_preferences.h" | ||||
| #include "atom/browser/window_list.h" | ||||
| #include "atom/common/options_switches.h" | ||||
|  | @ -281,6 +282,24 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( | |||
|   return new AtomBrowserMainParts; | ||||
| } | ||||
| 
 | ||||
| void AtomBrowserClient::WebNotificationAllowed( | ||||
|     int render_process_id, | ||||
|     const base::Callback<void(bool)>& callback) { | ||||
|   content::WebContents* web_contents = content::WebContents::FromRenderViewHost( | ||||
|       content::RenderViewHost::FromID(render_process_id, kDefaultRoutingID)); | ||||
|   if (!web_contents) { | ||||
|     callback.Run(false); | ||||
|     return; | ||||
|   } | ||||
|   auto permission_helper = | ||||
|       WebContentsPermissionHelper::FromWebContents(web_contents); | ||||
|   if (!permission_helper) { | ||||
|     callback.Run(false); | ||||
|     return; | ||||
|   } | ||||
|   permission_helper->RequestWebNotificationPermission(callback); | ||||
| } | ||||
| 
 | ||||
| void AtomBrowserClient::RenderProcessHostDestroyed( | ||||
|     content::RenderProcessHost* host) { | ||||
|   int process_id = host->GetID(); | ||||
|  |  | |||
|  | @ -81,6 +81,9 @@ class AtomBrowserClient : public brightray::BrowserClient, | |||
|   // brightray::BrowserClient:
 | ||||
|   brightray::BrowserMainParts* OverrideCreateBrowserMainParts( | ||||
|       const content::MainFunctionParams&) override; | ||||
|   void WebNotificationAllowed( | ||||
|       int render_process_id, | ||||
|       const base::Callback<void(bool)>& callback) override; | ||||
| 
 | ||||
|   // content::RenderProcessHostObserver:
 | ||||
|   void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ | |||
| #include "atom/browser/net/atom_url_request_job_factory.h" | ||||
| #include "atom/browser/net/asar/asar_protocol_handler.h" | ||||
| #include "atom/browser/net/http_protocol_handler.h" | ||||
| #include "atom/browser/atom_permission_manager.h" | ||||
| #include "atom/browser/web_view_manager.h" | ||||
| #include "atom/common/atom_version.h" | ||||
| #include "atom/common/chrome_version.h" | ||||
|  | @ -169,6 +170,12 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { | |||
|   return guest_manager_.get(); | ||||
| } | ||||
| 
 | ||||
| content::PermissionManager* AtomBrowserContext::GetPermissionManager() { | ||||
|   if (!permission_manager_.get()) | ||||
|     permission_manager_.reset(new AtomPermissionManager); | ||||
|   return permission_manager_.get(); | ||||
| } | ||||
| 
 | ||||
| scoped_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() { | ||||
|   DCHECK(!cert_verifier_); | ||||
|   cert_verifier_ = new AtomCertVerifier; | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ namespace atom { | |||
| class AtomDownloadManagerDelegate; | ||||
| class AtomCertVerifier; | ||||
| class AtomNetworkDelegate; | ||||
| class AtomPermissionManager; | ||||
| class AtomURLRequestJobFactory; | ||||
| class WebViewManager; | ||||
| 
 | ||||
|  | @ -37,6 +38,7 @@ class AtomBrowserContext : public brightray::BrowserContext { | |||
|   // content::BrowserContext:
 | ||||
|   content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; | ||||
|   content::BrowserPluginGuestManager* GetGuestManager() override; | ||||
|   content::PermissionManager* GetPermissionManager() override; | ||||
| 
 | ||||
|   // brightray::BrowserContext:
 | ||||
|   void RegisterPrefs(PrefRegistrySimple* pref_registry) override; | ||||
|  | @ -52,6 +54,7 @@ class AtomBrowserContext : public brightray::BrowserContext { | |||
|  private: | ||||
|   scoped_ptr<AtomDownloadManagerDelegate> download_manager_delegate_; | ||||
|   scoped_ptr<WebViewManager> guest_manager_; | ||||
|   scoped_ptr<AtomPermissionManager> permission_manager_; | ||||
| 
 | ||||
|   // Managed by brightray::BrowserContext.
 | ||||
|   AtomCertVerifier* cert_verifier_; | ||||
|  |  | |||
							
								
								
									
										136
									
								
								atom/browser/atom_permission_manager.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								atom/browser/atom_permission_manager.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,136 @@ | |||
| // Copyright (c) 2016 GitHub, Inc.
 | ||||
| // Use of this source code is governed by the MIT license that can be
 | ||||
| // found in the LICENSE file.
 | ||||
| 
 | ||||
| #include "atom/browser/atom_permission_manager.h" | ||||
| 
 | ||||
| #include "content/public/browser/child_process_security_policy.h" | ||||
| #include "content/public/browser/permission_type.h" | ||||
| #include "content/public/browser/render_frame_host.h" | ||||
| #include "content/public/browser/render_process_host.h" | ||||
| #include "content/public/browser/render_view_host.h" | ||||
| #include "content/public/browser/web_contents.h" | ||||
| 
 | ||||
| namespace atom { | ||||
| 
 | ||||
| namespace { | ||||
| 
 | ||||
| // Must be kept in sync with atom_browser_client.cc
 | ||||
| int kDefaultRoutingID = 2; | ||||
| 
 | ||||
| bool WebContentsDestroyed(int process_id) { | ||||
|   auto rvh = content::RenderViewHost::FromID(process_id, kDefaultRoutingID); | ||||
|   if (rvh) { | ||||
|     auto contents = content::WebContents::FromRenderViewHost(rvh); | ||||
|     return contents->IsBeingDestroyed(); | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| }  // namespace
 | ||||
| 
 | ||||
| AtomPermissionManager::AtomPermissionManager() | ||||
|     : request_id_(0) { | ||||
| } | ||||
| 
 | ||||
| AtomPermissionManager::~AtomPermissionManager() { | ||||
| } | ||||
| 
 | ||||
| void AtomPermissionManager::SetPermissionRequestHandler( | ||||
|     const RequestHandler& handler) { | ||||
|   if (handler.is_null() && !pending_requests_.empty()) { | ||||
|     for (const auto& request : pending_requests_) { | ||||
|       if (!WebContentsDestroyed(request.second.render_process_id)) | ||||
|         request.second.callback.Run(content::PERMISSION_STATUS_DENIED); | ||||
|     } | ||||
|     pending_requests_.clear(); | ||||
|   } | ||||
|   request_handler_ = handler; | ||||
| } | ||||
| 
 | ||||
| int AtomPermissionManager::RequestPermission( | ||||
|     content::PermissionType permission, | ||||
|     content::RenderFrameHost* render_frame_host, | ||||
|     const GURL& requesting_origin, | ||||
|     bool user_gesture, | ||||
|     const ResponseCallback& response_callback) { | ||||
|   int process_id = render_frame_host->GetProcess()->GetID(); | ||||
| 
 | ||||
|   if (permission == content::PermissionType::MIDI_SYSEX) { | ||||
|     content::ChildProcessSecurityPolicy::GetInstance()-> | ||||
|         GrantSendMidiSysExMessage(process_id); | ||||
|   } | ||||
| 
 | ||||
|   if (!request_handler_.is_null()) { | ||||
|     auto web_contents = | ||||
|         content::WebContents::FromRenderFrameHost(render_frame_host); | ||||
|     ++request_id_; | ||||
|     auto callback = base::Bind(&AtomPermissionManager::OnPermissionResponse, | ||||
|                                base::Unretained(this), | ||||
|                                request_id_, | ||||
|                                requesting_origin, | ||||
|                                response_callback); | ||||
|     pending_requests_[request_id_] = { process_id, callback }; | ||||
|     request_handler_.Run(web_contents, permission, callback); | ||||
|     return request_id_; | ||||
|   } | ||||
| 
 | ||||
|   response_callback.Run(content::PERMISSION_STATUS_GRANTED); | ||||
|   return kNoPendingOperation; | ||||
| } | ||||
| 
 | ||||
| void AtomPermissionManager::OnPermissionResponse( | ||||
|     int request_id, | ||||
|     const GURL& origin, | ||||
|     const ResponseCallback& callback, | ||||
|     content::PermissionStatus status) { | ||||
|   auto request = pending_requests_.find(request_id); | ||||
|   if (request != pending_requests_.end()) { | ||||
|     if (!WebContentsDestroyed(request->second.render_process_id)) | ||||
|       callback.Run(status); | ||||
|     pending_requests_.erase(request); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void AtomPermissionManager::CancelPermissionRequest(int request_id) { | ||||
|   auto request = pending_requests_.find(request_id); | ||||
|   if (request != pending_requests_.end()) { | ||||
|     if (!WebContentsDestroyed(request->second.render_process_id)) | ||||
|       request->second.callback.Run(content::PERMISSION_STATUS_DENIED); | ||||
|     pending_requests_.erase(request); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void AtomPermissionManager::ResetPermission( | ||||
|     content::PermissionType permission, | ||||
|     const GURL& requesting_origin, | ||||
|     const GURL& embedding_origin) { | ||||
| } | ||||
| 
 | ||||
| content::PermissionStatus AtomPermissionManager::GetPermissionStatus( | ||||
|     content::PermissionType permission, | ||||
|     const GURL& requesting_origin, | ||||
|     const GURL& embedding_origin) { | ||||
|   return content::PERMISSION_STATUS_GRANTED; | ||||
| } | ||||
| 
 | ||||
| void AtomPermissionManager::RegisterPermissionUsage( | ||||
|     content::PermissionType permission, | ||||
|     const GURL& requesting_origin, | ||||
|     const GURL& embedding_origin) { | ||||
| } | ||||
| 
 | ||||
| int AtomPermissionManager::SubscribePermissionStatusChange( | ||||
|     content::PermissionType permission, | ||||
|     const GURL& requesting_origin, | ||||
|     const GURL& embedding_origin, | ||||
|     const ResponseCallback& callback) { | ||||
|   return -1; | ||||
| } | ||||
| 
 | ||||
| void AtomPermissionManager::UnsubscribePermissionStatusChange( | ||||
|     int subscription_id) { | ||||
| } | ||||
| 
 | ||||
| }  // namespace atom
 | ||||
							
								
								
									
										84
									
								
								atom/browser/atom_permission_manager.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								atom/browser/atom_permission_manager.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,84 @@ | |||
| // Copyright (c) 2016 GitHub, Inc.
 | ||||
| // Use of this source code is governed by the MIT license that can be
 | ||||
| // found in the LICENSE file.
 | ||||
| 
 | ||||
| #ifndef ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_ | ||||
| #define ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_ | ||||
| 
 | ||||
| #include <map> | ||||
| 
 | ||||
| #include "base/callback.h" | ||||
| #include "content/public/browser/permission_manager.h" | ||||
| 
 | ||||
| namespace content { | ||||
| class WebContents; | ||||
| } | ||||
| 
 | ||||
| namespace atom { | ||||
| 
 | ||||
| class AtomPermissionManager : public content::PermissionManager { | ||||
|  public: | ||||
|   AtomPermissionManager(); | ||||
|   ~AtomPermissionManager() override; | ||||
| 
 | ||||
|   using ResponseCallback = | ||||
|       base::Callback<void(content::PermissionStatus)>; | ||||
|   using RequestHandler = | ||||
|       base::Callback<void(content::WebContents*, | ||||
|                           content::PermissionType, | ||||
|                           const ResponseCallback&)>; | ||||
| 
 | ||||
|   // Handler to dispatch permission requests in JS.
 | ||||
|   void SetPermissionRequestHandler(const RequestHandler& handler); | ||||
| 
 | ||||
|   // content::PermissionManager:
 | ||||
|   int RequestPermission( | ||||
|       content::PermissionType permission, | ||||
|       content::RenderFrameHost* render_frame_host, | ||||
|       const GURL& requesting_origin, | ||||
|       bool user_gesture, | ||||
|       const ResponseCallback& callback) override; | ||||
| 
 | ||||
|  protected: | ||||
|   void OnPermissionResponse(int request_id, | ||||
|                             const GURL& url, | ||||
|                             const ResponseCallback& callback, | ||||
|                             content::PermissionStatus status); | ||||
| 
 | ||||
|   // content::PermissionManager:
 | ||||
|   void CancelPermissionRequest(int request_id) override; | ||||
|   void ResetPermission(content::PermissionType permission, | ||||
|                        const GURL& requesting_origin, | ||||
|                        const GURL& embedding_origin) override; | ||||
|   content::PermissionStatus GetPermissionStatus( | ||||
|       content::PermissionType permission, | ||||
|       const GURL& requesting_origin, | ||||
|       const GURL& embedding_origin) override; | ||||
|   void RegisterPermissionUsage(content::PermissionType permission, | ||||
|                                const GURL& requesting_origin, | ||||
|                                const GURL& embedding_origin) override; | ||||
|   int SubscribePermissionStatusChange( | ||||
|       content::PermissionType permission, | ||||
|       const GURL& requesting_origin, | ||||
|       const GURL& embedding_origin, | ||||
|       const base::Callback<void(content::PermissionStatus)>& callback) override; | ||||
|   void UnsubscribePermissionStatusChange(int subscription_id) override; | ||||
| 
 | ||||
|  private: | ||||
|   struct RequestInfo { | ||||
|     int render_process_id; | ||||
|     ResponseCallback callback; | ||||
|   }; | ||||
| 
 | ||||
|   RequestHandler request_handler_; | ||||
| 
 | ||||
|   std::map<int, RequestInfo> pending_requests_; | ||||
| 
 | ||||
|   int request_id_; | ||||
| 
 | ||||
|   DISALLOW_COPY_AND_ASSIGN(AtomPermissionManager); | ||||
| }; | ||||
| 
 | ||||
| }  // namespace atom
 | ||||
| 
 | ||||
| #endif  // ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_
 | ||||
|  | @ -6,7 +6,38 @@ var slice = [].slice; | |||
| // Doesn't exist in early initialization.
 | ||||
| var webViewManager = null; | ||||
| 
 | ||||
| var supportedWebViewEvents = ['load-commit', 'did-finish-load', 'did-fail-load', 'did-frame-finish-load', 'did-start-loading', 'did-stop-loading', 'did-get-response-details', 'did-get-redirect-request', 'dom-ready', 'console-message', 'devtools-opened', 'devtools-closed', 'devtools-focused', 'new-window', 'will-navigate', 'did-navigate', 'did-navigate-in-page', 'close', 'crashed', 'gpu-crashed', 'plugin-crashed', 'destroyed', 'page-title-updated', 'page-favicon-updated', 'enter-html-full-screen', 'leave-html-full-screen', 'media-started-playing', 'media-paused', 'found-in-page', 'did-change-theme-color']; | ||||
| var supportedWebViewEvents = [ | ||||
|   'load-commit', | ||||
|   'did-finish-load', | ||||
|   'did-fail-load', | ||||
|   'did-frame-finish-load', | ||||
|   'did-start-loading', | ||||
|   'did-stop-loading', | ||||
|   'did-get-response-details', | ||||
|   'did-get-redirect-request', | ||||
|   'dom-ready', | ||||
|   'console-message', | ||||
|   'devtools-opened', | ||||
|   'devtools-closed', | ||||
|   'devtools-focused', | ||||
|   'new-window', | ||||
|   'will-navigate', | ||||
|   'did-navigate', | ||||
|   'did-navigate-in-page', | ||||
|   'close', | ||||
|   'crashed', | ||||
|   'gpu-crashed', | ||||
|   'plugin-crashed', | ||||
|   'destroyed', | ||||
|   'page-title-updated', | ||||
|   'page-favicon-updated', | ||||
|   'enter-html-full-screen', | ||||
|   'leave-html-full-screen', | ||||
|   'media-started-playing', | ||||
|   'media-paused', | ||||
|   'found-in-page', | ||||
|   'did-change-theme-color' | ||||
| ]; | ||||
| 
 | ||||
| var nextInstanceId = 0; | ||||
| var guestInstances = {}; | ||||
|  |  | |||
							
								
								
									
										94
									
								
								atom/browser/web_contents_permission_helper.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								atom/browser/web_contents_permission_helper.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,94 @@ | |||
| // Copyright (c) 2016 GitHub, Inc.
 | ||||
| // Use of this source code is governed by the MIT license that can be
 | ||||
| // found in the LICENSE file.
 | ||||
| 
 | ||||
| #include "atom/browser/web_contents_permission_helper.h" | ||||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| #include "atom/browser/atom_permission_manager.h" | ||||
| #include "brightray/browser/media/media_stream_devices_controller.h" | ||||
| #include "content/public/browser/browser_context.h" | ||||
| #include "content/public/browser/render_process_host.h" | ||||
| 
 | ||||
| DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPermissionHelper); | ||||
| 
 | ||||
| namespace atom { | ||||
| 
 | ||||
| namespace { | ||||
| 
 | ||||
| void MediaAccessAllowed( | ||||
|     const content::MediaStreamRequest& request, | ||||
|     const content::MediaResponseCallback& callback, | ||||
|     bool allowed) { | ||||
|   brightray::MediaStreamDevicesController controller(request, callback); | ||||
|   if (allowed) | ||||
|     controller.Accept(); | ||||
|   else | ||||
|     controller.Deny(content::MEDIA_DEVICE_PERMISSION_DENIED); | ||||
| } | ||||
| 
 | ||||
| void OnPointerLockResponse(content::WebContents* web_contents, bool allowed) { | ||||
|   if (web_contents) | ||||
|     web_contents->GotResponseToLockMouseRequest(allowed); | ||||
| } | ||||
| 
 | ||||
| void OnPermissionResponse(const base::Callback<void(bool)>& callback, | ||||
|                           content::PermissionStatus status) { | ||||
|   if (status == content::PERMISSION_STATUS_GRANTED) | ||||
|     callback.Run(true); | ||||
|   else | ||||
|     callback.Run(false); | ||||
| } | ||||
| 
 | ||||
| }  // namespace
 | ||||
| 
 | ||||
| WebContentsPermissionHelper::WebContentsPermissionHelper( | ||||
|     content::WebContents* web_contents) | ||||
|     : web_contents_(web_contents) { | ||||
| } | ||||
| 
 | ||||
| WebContentsPermissionHelper::~WebContentsPermissionHelper() { | ||||
| } | ||||
| 
 | ||||
| void WebContentsPermissionHelper::RequestPermission( | ||||
|     content::PermissionType permission, | ||||
|     const base::Callback<void(bool)>& callback, | ||||
|     bool user_gesture) { | ||||
|   auto rfh = web_contents_->GetMainFrame(); | ||||
|   auto permission_manager = static_cast<AtomPermissionManager*>( | ||||
|       web_contents_->GetBrowserContext()->GetPermissionManager()); | ||||
|   auto origin = web_contents_->GetLastCommittedURL(); | ||||
|   permission_manager->RequestPermission( | ||||
|       permission, rfh, origin, user_gesture, | ||||
|       base::Bind(&OnPermissionResponse, callback)); | ||||
| } | ||||
| 
 | ||||
| void WebContentsPermissionHelper::RequestFullscreenPermission( | ||||
|     const base::Callback<void(bool)>& callback) { | ||||
|   RequestPermission((content::PermissionType)(PermissionType::FULLSCREEN), | ||||
|                     callback); | ||||
| } | ||||
| 
 | ||||
| void WebContentsPermissionHelper::RequestMediaAccessPermission( | ||||
|     const content::MediaStreamRequest& request, | ||||
|     const content::MediaResponseCallback& response_callback) { | ||||
|   auto callback = base::Bind(&MediaAccessAllowed, request, response_callback); | ||||
|   // The permission type doesn't matter here, AUDIO_CAPTURE/VIDEO_CAPTURE
 | ||||
|   // are presented as same type in content_converter.h.
 | ||||
|   RequestPermission(content::PermissionType::AUDIO_CAPTURE, callback); | ||||
| } | ||||
| 
 | ||||
| void WebContentsPermissionHelper::RequestWebNotificationPermission( | ||||
|     const base::Callback<void(bool)>& callback) { | ||||
|   RequestPermission(content::PermissionType::NOTIFICATIONS, callback); | ||||
| } | ||||
| 
 | ||||
| void WebContentsPermissionHelper::RequestPointerLockPermission( | ||||
|     bool user_gesture) { | ||||
|   RequestPermission((content::PermissionType)(PermissionType::POINTER_LOCK), | ||||
|                     base::Bind(&OnPointerLockResponse, web_contents_), | ||||
|                     user_gesture); | ||||
| } | ||||
| 
 | ||||
| }  // namespace atom
 | ||||
							
								
								
									
										50
									
								
								atom/browser/web_contents_permission_helper.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								atom/browser/web_contents_permission_helper.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | |||
| // Copyright (c) 2016 GitHub, Inc.
 | ||||
| // Use of this source code is governed by the MIT license that can be
 | ||||
| // found in the LICENSE file.
 | ||||
| 
 | ||||
| #ifndef ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ | ||||
| #define ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ | ||||
| 
 | ||||
| #include "content/public/browser/permission_type.h" | ||||
| #include "content/public/browser/web_contents_user_data.h" | ||||
| #include "content/public/common/media_stream_request.h" | ||||
| 
 | ||||
| namespace atom { | ||||
| 
 | ||||
| // Applies the permission requested for WebContents.
 | ||||
| class WebContentsPermissionHelper | ||||
|     : public content::WebContentsUserData<WebContentsPermissionHelper> { | ||||
|  public: | ||||
|   ~WebContentsPermissionHelper() override; | ||||
| 
 | ||||
|   enum class PermissionType { | ||||
|     POINTER_LOCK = static_cast<int>(content::PermissionType::NUM) + 1, | ||||
|     FULLSCREEN | ||||
|   }; | ||||
| 
 | ||||
|   void RequestFullscreenPermission( | ||||
|       const base::Callback<void(bool)>& callback); | ||||
|   void RequestMediaAccessPermission( | ||||
|       const content::MediaStreamRequest& request, | ||||
|       const content::MediaResponseCallback& callback); | ||||
|   void RequestWebNotificationPermission( | ||||
|       const base::Callback<void(bool)>& callback); | ||||
|   void RequestPointerLockPermission(bool user_gesture); | ||||
| 
 | ||||
|  private: | ||||
|   explicit WebContentsPermissionHelper(content::WebContents* web_contents); | ||||
|   friend class content::WebContentsUserData<WebContentsPermissionHelper>; | ||||
| 
 | ||||
|   void RequestPermission( | ||||
|       content::PermissionType permission, | ||||
|       const base::Callback<void(bool)>& callback, | ||||
|       bool user_gesture = false); | ||||
| 
 | ||||
|   content::WebContents* web_contents_; | ||||
| 
 | ||||
|   DISALLOW_COPY_AND_ASSIGN(WebContentsPermissionHelper); | ||||
| }; | ||||
| 
 | ||||
| }  // namespace atom
 | ||||
| 
 | ||||
| #endif  // ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_
 | ||||
|  | @ -7,6 +7,8 @@ | |||
| #include <string> | ||||
| #include <vector> | ||||
| 
 | ||||
| #include "atom/browser/api/atom_api_web_contents.h" | ||||
| #include "atom/browser/web_contents_permission_helper.h" | ||||
| #include "atom/common/native_mate_converters/callback.h" | ||||
| #include "atom/common/native_mate_converters/string16_converter.h" | ||||
| #include "content/public/browser/web_contents.h" | ||||
|  | @ -98,6 +100,55 @@ v8::Local<v8::Value> Converter<ContextMenuParamsWithWebContents>::ToV8( | |||
|   return mate::ConvertToV8(isolate, dict); | ||||
| } | ||||
| 
 | ||||
| // static
 | ||||
| bool Converter<content::PermissionStatus>::FromV8( | ||||
|     v8::Isolate* isolate, | ||||
|     v8::Local<v8::Value> val, | ||||
|     content::PermissionStatus* out) { | ||||
|   bool result; | ||||
|   if (!ConvertFromV8(isolate, val, &result)) | ||||
|     return false; | ||||
| 
 | ||||
|   if (result) | ||||
|     *out = content::PERMISSION_STATUS_GRANTED; | ||||
|   else | ||||
|     *out = content::PERMISSION_STATUS_DENIED; | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| // static
 | ||||
| v8::Local<v8::Value> Converter<content::PermissionType>::ToV8( | ||||
|     v8::Isolate* isolate, const content::PermissionType& val) { | ||||
|   using PermissionType = atom::WebContentsPermissionHelper::PermissionType; | ||||
|   switch (val) { | ||||
|     case content::PermissionType::MIDI_SYSEX: | ||||
|       return StringToV8(isolate, "midiSysex"); | ||||
|     case content::PermissionType::PUSH_MESSAGING: | ||||
|       return StringToV8(isolate, "pushMessaging"); | ||||
|     case content::PermissionType::NOTIFICATIONS: | ||||
|       return StringToV8(isolate, "notifications"); | ||||
|     case content::PermissionType::GEOLOCATION: | ||||
|       return StringToV8(isolate, "geolocation"); | ||||
|     case content::PermissionType::AUDIO_CAPTURE: | ||||
|     case content::PermissionType::VIDEO_CAPTURE: | ||||
|       return StringToV8(isolate, "media"); | ||||
|     case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER: | ||||
|       return StringToV8(isolate, "mediaKeySystem"); | ||||
|     case content::PermissionType::MIDI: | ||||
|       return StringToV8(isolate, "midi"); | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
| 
 | ||||
|   if (val == (content::PermissionType)(PermissionType::POINTER_LOCK)) | ||||
|     return StringToV8(isolate, "pointerLock"); | ||||
|   else if (val == (content::PermissionType)(PermissionType::FULLSCREEN)) | ||||
|     return StringToV8(isolate, "fullscreen"); | ||||
| 
 | ||||
|   return StringToV8(isolate, "unknown"); | ||||
| } | ||||
| 
 | ||||
| // static
 | ||||
| bool Converter<content::StopFindAction>::FromV8( | ||||
|     v8::Isolate* isolate, | ||||
|  | @ -119,4 +170,10 @@ bool Converter<content::StopFindAction>::FromV8( | |||
|   return true; | ||||
| } | ||||
| 
 | ||||
| // static
 | ||||
| v8::Local<v8::Value> Converter<content::WebContents*>::ToV8( | ||||
|     v8::Isolate* isolate, content::WebContents* val) { | ||||
|   return atom::api::WebContents::CreateFrom(isolate, val).ToV8(); | ||||
| } | ||||
| 
 | ||||
| }  // namespace mate
 | ||||
|  |  | |||
|  | @ -7,7 +7,9 @@ | |||
| 
 | ||||
| #include <utility> | ||||
| 
 | ||||
| #include "content/public/browser/permission_type.h" | ||||
| #include "content/public/common/menu_item.h" | ||||
| #include "content/public/common/permission_status.mojom.h" | ||||
| #include "content/public/common/stop_find_action.h" | ||||
| #include "native_mate/converter.h" | ||||
| 
 | ||||
|  | @ -33,12 +35,30 @@ struct Converter<ContextMenuParamsWithWebContents> { | |||
|                                    const ContextMenuParamsWithWebContents& val); | ||||
| }; | ||||
| 
 | ||||
| template<> | ||||
| struct Converter<content::PermissionStatus> { | ||||
|   static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, | ||||
|                      content::PermissionStatus* out); | ||||
| }; | ||||
| 
 | ||||
| template<> | ||||
| struct Converter<content::PermissionType> { | ||||
|   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, | ||||
|                                    const content::PermissionType& val); | ||||
| }; | ||||
| 
 | ||||
| template<> | ||||
| struct Converter<content::StopFindAction> { | ||||
|   static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, | ||||
|                      content::StopFindAction* out); | ||||
| }; | ||||
| 
 | ||||
| template<> | ||||
| struct Converter<content::WebContents*> { | ||||
|   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, | ||||
|                                    content::WebContents* val); | ||||
| }; | ||||
| 
 | ||||
| }  // namespace mate
 | ||||
| 
 | ||||
| #endif  // ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_
 | ||||
|  |  | |||
|  | @ -290,6 +290,29 @@ myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, c | |||
| }); | ||||
| ``` | ||||
| 
 | ||||
| #### `ses.setPermissionRequestHandler(handler)` | ||||
| 
 | ||||
| * `handler` Function | ||||
|   * `webContents` Object - [WebContents](web-contents.md) requesting the permission. | ||||
|   * `permission`  String - Enum of 'media', 'geolocation', 'notifications', 'midiSysex', 'pointerLock', 'fullscreen'. | ||||
|   * `callback`  Function - Allow or deny the permission. | ||||
| 
 | ||||
| Sets the handler which can be used to respond to permission requests for the `session`. | ||||
| Calling `callback(true)` will allow the permission and `callback(false)` will reject it. | ||||
| 
 | ||||
| ```javascript | ||||
| session.fromPartition(partition).setPermissionRequestHandler(function(webContents, permission, callback) { | ||||
|   if (webContents.getURL() === host) { | ||||
|     if (permission == "notifications") { | ||||
|       callback(false); // denied. | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   callback(true); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| #### `ses.webRequest` | ||||
| 
 | ||||
| The `webRequest` API set allows to intercept and modify contents of a request at | ||||
|  |  | |||
|  | @ -144,6 +144,8 @@ | |||
|       'atom/browser/atom_browser_main_parts_posix.cc', | ||||
|       'atom/browser/atom_javascript_dialog_manager.cc', | ||||
|       'atom/browser/atom_javascript_dialog_manager.h', | ||||
|       'atom/browser/atom_permission_manager.cc', | ||||
|       'atom/browser/atom_permission_manager.h', | ||||
|       'atom/browser/atom_quota_permission_context.cc', | ||||
|       'atom/browser/atom_quota_permission_context.h', | ||||
|       'atom/browser/atom_resource_dispatcher_host_delegate.cc', | ||||
|  | @ -256,6 +258,8 @@ | |||
|       'atom/browser/ui/x/window_state_watcher.h', | ||||
|       'atom/browser/ui/x/x_window_utils.cc', | ||||
|       'atom/browser/ui/x/x_window_utils.h', | ||||
|       'atom/browser/web_contents_permission_helper.cc', | ||||
|       'atom/browser/web_contents_permission_helper.h', | ||||
|       'atom/browser/web_contents_preferences.cc', | ||||
|       'atom/browser/web_contents_preferences.h', | ||||
|       'atom/browser/web_dialog_helper.cc', | ||||
|  |  | |||
							
								
								
									
										5
									
								
								spec/fixtures/pages/permissions/geolocation.html
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								spec/fixtures/pages/permissions/geolocation.html
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| <script> | ||||
| navigator.geolocation.getCurrentPosition(() => {}, (err) => { | ||||
|   require('electron').ipcRenderer.sendToHost('message', err.message); | ||||
| }); | ||||
| </script> | ||||
							
								
								
									
										7
									
								
								spec/fixtures/pages/permissions/media.html
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								spec/fixtures/pages/permissions/media.html
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| <script> | ||||
|   navigator.webkitGetUserMedia({ audio: true, video: true }, function(mediaStream) { | ||||
| 
 | ||||
|   }, function(err) { | ||||
|     require('electron').ipcRenderer.sendToHost('message', err.name); | ||||
|   }); | ||||
| </script> | ||||
							
								
								
									
										5
									
								
								spec/fixtures/pages/permissions/midi.html
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								spec/fixtures/pages/permissions/midi.html
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| <script> | ||||
| navigator.requestMIDIAccess({sysex: true}).then(() => {}, (err) => { | ||||
|   require('electron').ipcRenderer.sendToHost('message', err.name); | ||||
| }); | ||||
| </script> | ||||
|  | @ -624,7 +624,7 @@ describe('<webview> tag', function() { | |||
|       return document.body.appendChild(webview); | ||||
|     }); | ||||
|   }); | ||||
|   return xdescribe('did-change-theme-color event', function() { | ||||
|   xdescribe('did-change-theme-color event', function() { | ||||
|     return it('emits when theme color changes', function(done) { | ||||
|       webview.addEventListener('did-change-theme-color', function() { | ||||
|         return done(); | ||||
|  | @ -633,4 +633,55 @@ describe('<webview> tag', function() { | |||
|       return document.body.appendChild(webview); | ||||
|     }); | ||||
|   }); | ||||
|   describe('permission-request event', function() { | ||||
|     function setUpRequestHandler(webview, requested_permission) { | ||||
|       const session = require('electron').remote.session; | ||||
|       var listener = function(webContents, permission, callback) { | ||||
|         if (webContents.getId() === webview.getId() ) { | ||||
|           assert.equal(permission, requested_permission); | ||||
|           callback(false); | ||||
|         } | ||||
|       }; | ||||
|       session.fromPartition(webview.partition).setPermissionRequestHandler(listener); | ||||
|     } | ||||
| 
 | ||||
|     it ('emits when using navigator.getUserMedia api', function(done) { | ||||
|       webview.addEventListener('ipc-message', function(e) { | ||||
|         assert(e.channel, 'message'); | ||||
|         assert(e.args, ['PermissionDeniedError']); | ||||
|         done(); | ||||
|       }); | ||||
|       webview.src = "file://" + fixtures + "/pages/permissions/media.html"; | ||||
|       webview.partition = "permissionTest"; | ||||
|       webview.setAttribute('nodeintegration', 'on'); | ||||
|       setUpRequestHandler(webview, "media"); | ||||
|       document.body.appendChild(webview); | ||||
|     }); | ||||
| 
 | ||||
|     it ('emits when using navigator.geolocation api', function(done) { | ||||
|       webview.addEventListener('ipc-message', function(e) { | ||||
|         assert(e.channel, 'message'); | ||||
|         assert(e.args, ['ERROR(1): User denied Geolocation']); | ||||
|         done(); | ||||
|       }); | ||||
|       webview.src = "file://" + fixtures + "/pages/permissions/geolocation.html"; | ||||
|       webview.partition = "permissionTest"; | ||||
|       webview.setAttribute('nodeintegration', 'on'); | ||||
|       setUpRequestHandler(webview, "geolocation"); | ||||
|       document.body.appendChild(webview); | ||||
|     }); | ||||
| 
 | ||||
|     it ('emits when using navigator.requestMIDIAccess api', function(done) { | ||||
|       webview.addEventListener('ipc-message', function(e) { | ||||
|         assert(e.channel, 'message'); | ||||
|         assert(e.args, ['SecurityError']); | ||||
|         done(); | ||||
|       }); | ||||
|       webview.src = "file://" + fixtures + "/pages/permissions/midi.html"; | ||||
|       webview.partition = "permissionTest"; | ||||
|       webview.setAttribute('nodeintegration', 'on'); | ||||
|       setUpRequestHandler(webview, "midiSysex"); | ||||
|       document.body.appendChild(webview); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Cheng Zhao
				Cheng Zhao