add pointerlock permission type

This commit is contained in:
Robo 2016-02-01 15:13:49 +05:30
parent db26dcaf4c
commit 45eada306f
7 changed files with 89 additions and 19 deletions

View file

@ -457,6 +457,15 @@ void WebContents::RequestMediaAccessPermission(
permission_helper->RequestMediaAccessPermission(request, callback); 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) { void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
// Do nothing, we override this method just to avoid compilation error since // Do nothing, we override this method just to avoid compilation error since
// there are two virtual functions named BeforeUnloadFired. // there are two virtual functions named BeforeUnloadFired.

View file

@ -199,6 +199,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
content::WebContents* web_contents, content::WebContents* web_contents,
const content::MediaStreamRequest& request, const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback) override; const content::MediaResponseCallback& callback) override;
void RequestToLockMouse(
content::WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) override;
// content::WebContentsObserver: // content::WebContentsObserver:
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;

View file

@ -8,10 +8,28 @@
#include "content/public/browser/permission_type.h" #include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_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" #include "content/public/browser/web_contents.h"
namespace atom { 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() AtomPermissionManager::AtomPermissionManager()
: request_id_(0) { : request_id_(0) {
} }
@ -22,8 +40,10 @@ AtomPermissionManager::~AtomPermissionManager() {
void AtomPermissionManager::SetPermissionRequestHandler( void AtomPermissionManager::SetPermissionRequestHandler(
const RequestHandler& handler) { const RequestHandler& handler) {
if (handler.is_null() && !pending_requests_.empty()) { if (handler.is_null() && !pending_requests_.empty()) {
for (const auto& request : pending_requests_) for (const auto& request : pending_requests_) {
request.second.Run(content::PERMISSION_STATUS_DENIED); if (!WebContentsDestroyed(request.second.render_process_id))
request.second.callback.Run(content::PERMISSION_STATUS_DENIED);
}
pending_requests_.clear(); pending_requests_.clear();
} }
request_handler_ = handler; request_handler_ = handler;
@ -35,9 +55,11 @@ int AtomPermissionManager::RequestPermission(
const GURL& requesting_origin, const GURL& requesting_origin,
bool user_gesture, bool user_gesture,
const ResponseCallback& response_callback) { const ResponseCallback& response_callback) {
int process_id = render_frame_host->GetProcess()->GetID();
if (permission == content::PermissionType::MIDI_SYSEX) { if (permission == content::PermissionType::MIDI_SYSEX) {
content::ChildProcessSecurityPolicy::GetInstance()-> content::ChildProcessSecurityPolicy::GetInstance()->
GrantSendMidiSysExMessage(render_frame_host->GetProcess()->GetID()); GrantSendMidiSysExMessage(process_id);
} }
if (!request_handler_.is_null()) { if (!request_handler_.is_null()) {
@ -49,7 +71,7 @@ int AtomPermissionManager::RequestPermission(
request_id_, request_id_,
requesting_origin, requesting_origin,
response_callback); response_callback);
pending_requests_[request_id_] = callback; pending_requests_[request_id_] = { process_id, callback };
request_handler_.Run(web_contents, permission, callback); request_handler_.Run(web_contents, permission, callback);
return request_id_; return request_id_;
} }
@ -63,14 +85,19 @@ void AtomPermissionManager::OnPermissionResponse(
const GURL& origin, const GURL& origin,
const ResponseCallback& callback, const ResponseCallback& callback,
content::PermissionStatus status) { content::PermissionStatus status) {
callback.Run(status); auto request = pending_requests_.find(request_id);
pending_requests_.erase(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) { void AtomPermissionManager::CancelPermissionRequest(int request_id) {
auto request = pending_requests_.find(request_id); auto request = pending_requests_.find(request_id);
if (request != pending_requests_.end()) { if (request != pending_requests_.end()) {
request->second.Run(content::PERMISSION_STATUS_DENIED); if (!WebContentsDestroyed(request->second.render_process_id))
request->second.callback.Run(content::PERMISSION_STATUS_DENIED);
pending_requests_.erase(request); pending_requests_.erase(request);
} }
} }

View file

@ -65,9 +65,14 @@ class AtomPermissionManager : public content::PermissionManager {
void UnsubscribePermissionStatusChange(int subscription_id) override; void UnsubscribePermissionStatusChange(int subscription_id) override;
private: private:
struct RequestInfo {
int render_process_id;
ResponseCallback callback;
};
RequestHandler request_handler_; RequestHandler request_handler_;
std::map<int, ResponseCallback> pending_requests_; std::map<int, RequestInfo> pending_requests_;
int request_id_; int request_id_;

View file

@ -66,6 +66,11 @@ void MediaAccessAllowed(
callback.Run(devices, result, scoped_ptr<content::MediaStreamUI>()); callback.Run(devices, result, scoped_ptr<content::MediaStreamUI>());
} }
void OnPointerLockResponse(content::WebContents* web_contents, bool allowed) {
if (web_contents)
web_contents->GotResponseToLockMouseRequest(allowed);
}
void OnPermissionResponse(const base::Callback<void(bool)>& callback, void OnPermissionResponse(const base::Callback<void(bool)>& callback,
content::PermissionStatus status) { content::PermissionStatus status) {
if (status == content::PERMISSION_STATUS_GRANTED) if (status == content::PERMISSION_STATUS_GRANTED)
@ -86,12 +91,12 @@ WebContentsPermissionHelper::~WebContentsPermissionHelper() {
void WebContentsPermissionHelper::RequestPermission( void WebContentsPermissionHelper::RequestPermission(
content::PermissionType permission, content::PermissionType permission,
const base::Callback<void(bool)>& callback) { const base::Callback<void(bool)>& callback,
bool user_gesture) {
auto rfh = web_contents_->GetMainFrame(); auto rfh = web_contents_->GetMainFrame();
auto permission_manager = static_cast<AtomPermissionManager*>( auto permission_manager = static_cast<AtomPermissionManager*>(
web_contents_->GetBrowserContext()->GetPermissionManager()); web_contents_->GetBrowserContext()->GetPermissionManager());
auto origin = web_contents_->GetLastCommittedURL(); auto origin = web_contents_->GetLastCommittedURL();
bool user_gesture = false;
permission_manager->RequestPermission( permission_manager->RequestPermission(
permission, rfh, origin, user_gesture, permission, rfh, origin, user_gesture,
base::Bind(&OnPermissionResponse, callback)); base::Bind(&OnPermissionResponse, callback));
@ -111,4 +116,11 @@ void WebContentsPermissionHelper::RequestWebNotificationPermission(
RequestPermission(content::PermissionType::NOTIFICATIONS, 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 } // namespace atom

View file

@ -17,11 +17,17 @@ class WebContentsPermissionHelper
public: public:
~WebContentsPermissionHelper() override; ~WebContentsPermissionHelper() override;
enum class PermissionType {
POINTER_LOCK = static_cast<int>(content::PermissionType::NUM) + 1,
FULLSCREEN
};
void RequestMediaAccessPermission( void RequestMediaAccessPermission(
const content::MediaStreamRequest& request, const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback); const content::MediaResponseCallback& callback);
void RequestWebNotificationPermission( void RequestWebNotificationPermission(
const base::Callback<void(bool)>& callback); const base::Callback<void(bool)>& callback);
void RequestPointerLockPermission(bool user_gesture);
private: private:
explicit WebContentsPermissionHelper(content::WebContents* web_contents); explicit WebContentsPermissionHelper(content::WebContents* web_contents);
@ -29,7 +35,8 @@ class WebContentsPermissionHelper
void RequestPermission( void RequestPermission(
content::PermissionType permission, content::PermissionType permission,
const base::Callback<void(bool)>& callback); const base::Callback<void(bool)>& callback,
bool user_gesture = false);
content::WebContents* web_contents_; content::WebContents* web_contents_;

View file

@ -8,6 +8,7 @@
#include <vector> #include <vector>
#include "atom/browser/api/atom_api_web_contents.h" #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/callback.h"
#include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/string16_converter.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
@ -104,16 +105,14 @@ bool Converter<content::PermissionStatus>::FromV8(
v8::Isolate* isolate, v8::Isolate* isolate,
v8::Local<v8::Value> val, v8::Local<v8::Value> val,
content::PermissionStatus* out) { content::PermissionStatus* out) {
std::string status; bool result;
if (!ConvertFromV8(isolate, val, &status)) if (!ConvertFromV8(isolate, val, &result))
return false; return false;
if (status == "granted") if (result)
*out = content::PERMISSION_STATUS_GRANTED; *out = content::PERMISSION_STATUS_GRANTED;
else if (status == "denied" || status.empty())
*out = content::PERMISSION_STATUS_DENIED;
else else
return false; *out = content::PERMISSION_STATUS_DENIED;
return true; return true;
} }
@ -121,6 +120,7 @@ bool Converter<content::PermissionStatus>::FromV8(
// static // static
v8::Local<v8::Value> Converter<content::PermissionType>::ToV8( v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
v8::Isolate* isolate, const content::PermissionType& val) { v8::Isolate* isolate, const content::PermissionType& val) {
using PermissionType = atom::WebContentsPermissionHelper::PermissionType;
switch (val) { switch (val) {
case content::PermissionType::MIDI_SYSEX: case content::PermissionType::MIDI_SYSEX:
return StringToV8(isolate, "midiSysex"); return StringToV8(isolate, "midiSysex");
@ -137,10 +137,16 @@ v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
return StringToV8(isolate, "mediaKeySystem"); return StringToV8(isolate, "mediaKeySystem");
case content::PermissionType::MIDI: case content::PermissionType::MIDI:
return StringToV8(isolate, "midi"); return StringToV8(isolate, "midi");
case content::PermissionType::DURABLE_STORAGE:
default: default:
return StringToV8(isolate, "unknown"); 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 // static