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…
Reference in a new issue