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);
}
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.

View file

@ -199,6 +199,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
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;

View file

@ -8,10 +8,28 @@
#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) {
}
@ -22,8 +40,10 @@ AtomPermissionManager::~AtomPermissionManager() {
void AtomPermissionManager::SetPermissionRequestHandler(
const RequestHandler& handler) {
if (handler.is_null() && !pending_requests_.empty()) {
for (const auto& request : pending_requests_)
request.second.Run(content::PERMISSION_STATUS_DENIED);
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;
@ -35,9 +55,11 @@ int AtomPermissionManager::RequestPermission(
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(render_frame_host->GetProcess()->GetID());
GrantSendMidiSysExMessage(process_id);
}
if (!request_handler_.is_null()) {
@ -49,7 +71,7 @@ int AtomPermissionManager::RequestPermission(
request_id_,
requesting_origin,
response_callback);
pending_requests_[request_id_] = callback;
pending_requests_[request_id_] = { process_id, callback };
request_handler_.Run(web_contents, permission, callback);
return request_id_;
}
@ -63,14 +85,19 @@ void AtomPermissionManager::OnPermissionResponse(
const GURL& origin,
const ResponseCallback& callback,
content::PermissionStatus status) {
callback.Run(status);
pending_requests_.erase(request_id);
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()) {
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);
}
}

View file

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

View file

@ -66,6 +66,11 @@ void MediaAccessAllowed(
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,
content::PermissionStatus status) {
if (status == content::PERMISSION_STATUS_GRANTED)
@ -86,12 +91,12 @@ WebContentsPermissionHelper::~WebContentsPermissionHelper() {
void WebContentsPermissionHelper::RequestPermission(
content::PermissionType permission,
const base::Callback<void(bool)>& callback) {
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();
bool user_gesture = false;
permission_manager->RequestPermission(
permission, rfh, origin, user_gesture,
base::Bind(&OnPermissionResponse, callback));
@ -111,4 +116,11 @@ void WebContentsPermissionHelper::RequestWebNotificationPermission(
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

View file

@ -17,11 +17,17 @@ class WebContentsPermissionHelper
public:
~WebContentsPermissionHelper() override;
enum class PermissionType {
POINTER_LOCK = static_cast<int>(content::PermissionType::NUM) + 1,
FULLSCREEN
};
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);
@ -29,7 +35,8 @@ class WebContentsPermissionHelper
void RequestPermission(
content::PermissionType permission,
const base::Callback<void(bool)>& callback);
const base::Callback<void(bool)>& callback,
bool user_gesture = false);
content::WebContents* web_contents_;

View file

@ -8,6 +8,7 @@
#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"
@ -104,16 +105,14 @@ bool Converter<content::PermissionStatus>::FromV8(
v8::Isolate* isolate,
v8::Local<v8::Value> val,
content::PermissionStatus* out) {
std::string status;
if (!ConvertFromV8(isolate, val, &status))
bool result;
if (!ConvertFromV8(isolate, val, &result))
return false;
if (status == "granted")
if (result)
*out = content::PERMISSION_STATUS_GRANTED;
else if (status == "denied" || status.empty())
*out = content::PERMISSION_STATUS_DENIED;
else
return false;
*out = content::PERMISSION_STATUS_DENIED;
return true;
}
@ -121,6 +120,7 @@ bool Converter<content::PermissionStatus>::FromV8(
// 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");
@ -137,10 +137,16 @@ v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
return StringToV8(isolate, "mediaKeySystem");
case content::PermissionType::MIDI:
return StringToV8(isolate, "midi");
case content::PermissionType::DURABLE_STORAGE:
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