diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/permissions/permission_service_impl.cc | 6 | ||||
-rw-r--r-- | content/child/blink_platform_impl.cc | 25 | ||||
-rw-r--r-- | content/child/blink_platform_impl.h | 5 | ||||
-rw-r--r-- | content/child/permissions/OWNERS | 1 | ||||
-rw-r--r-- | content/child/permissions/permission_manager.cc | 155 | ||||
-rw-r--r-- | content/child/permissions/permission_manager.h | 87 | ||||
-rw-r--r-- | content/child/permissions/permission_manager_thread_proxy.cc | 74 | ||||
-rw-r--r-- | content/child/permissions/permission_manager_thread_proxy.h | 54 | ||||
-rw-r--r-- | content/common/permission_service.mojom | 3 | ||||
-rw-r--r-- | content/content_child.gypi | 4 | ||||
-rw-r--r-- | content/renderer/render_frame_impl.cc | 8 | ||||
-rw-r--r-- | content/renderer/render_frame_impl.h | 8 |
12 files changed, 421 insertions, 9 deletions
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc index 333623a..940e783 100644 --- a/content/browser/permissions/permission_service_impl.cc +++ b/content/browser/permissions/permission_service_impl.cc @@ -14,10 +14,12 @@ PermissionType PermissionNameToPermissionType(PermissionName name) { switch(name) { case PERMISSION_NAME_GEOLOCATION: return PERMISSION_GEOLOCATION; - case PERMISSION_NAME_MIDI_SYSEX: - return PERMISSION_MIDI_SYSEX; case PERMISSION_NAME_NOTIFICATIONS: return PERMISSION_NOTIFICATIONS; + case PERMISSION_NAME_PUSH_NOTIFICATIONS: + return PERMISSION_PUSH_MESSAGING; + case PERMISSION_NAME_MIDI_SYSEX: + return PERMISSION_MIDI_SYSEX; case PERMISSION_NAME_PROTECTED_MEDIA_IDENTIFIER: return PERMISSION_PROTECTED_MEDIA_IDENTIFIER; } diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index 1874a5b6..db0ba13 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc @@ -35,6 +35,8 @@ #include "content/child/navigator_connect/navigator_connect_provider.h" #include "content/child/notifications/notification_dispatcher.h" #include "content/child/notifications/notification_manager.h" +#include "content/child/permissions/permission_manager.h" +#include "content/child/permissions/permission_manager_thread_proxy.h" #include "content/child/push_messaging/push_dispatcher.h" #include "content/child/push_messaging/push_provider.h" #include "content/child/thread_safe_sender.h" @@ -442,6 +444,8 @@ void BlinkPlatformImpl::InternalInit() { notification_dispatcher_ = ChildThreadImpl::current()->notification_dispatcher(); push_dispatcher_ = ChildThreadImpl::current()->push_dispatcher(); + permission_client_.reset(new PermissionManager( + ChildThreadImpl::current()->service_registry())); } if (main_thread_task_runner_.get()) { @@ -1023,13 +1027,10 @@ blink::WebGestureCurve* BlinkPlatformImpl::createFlingAnimationCurve( blink::WebGestureDevice device_source, const blink::WebFloatPoint& velocity, const blink::WebSize& cumulative_scroll) { - bool is_main_thread = - main_thread_task_runner_.get() && - main_thread_task_runner_->BelongsToCurrentThread(); return WebGestureCurveImpl::CreateFromDefaultPlatformCurve( gfx::Vector2dF(velocity.x, velocity.y), gfx::Vector2dF(cumulative_scroll.width, cumulative_scroll.height), - is_main_thread).release(); + IsMainThread()).release(); } void BlinkPlatformImpl::didStartWorkerRunLoop() { @@ -1082,6 +1083,17 @@ BlinkPlatformImpl::navigatorConnectProvider() { thread_safe_sender_.get(), main_thread_task_runner_); } +blink::WebPermissionClient* BlinkPlatformImpl::permissionClient() { + if (!permission_client_.get()) + return nullptr; + + if (IsMainThread()) + return permission_client_.get(); + + return PermissionManagerThreadProxy::GetThreadInstance( + main_thread_task_runner_.get(), permission_client_.get()); +} + WebThemeEngine* BlinkPlatformImpl::themeEngine() { return &native_theme_engine_; } @@ -1234,6 +1246,11 @@ BlinkPlatformImpl::MainTaskRunnerForCurrentThread() { } } +bool BlinkPlatformImpl::IsMainThread() const { + return main_thread_task_runner_.get() && + main_thread_task_runner_->BelongsToCurrentThread(); +} + WebString BlinkPlatformImpl::domCodeStringFromEnum(int dom_code) { return WebString::fromUTF8(ui::KeycodeConverter::DomCodeToCodeString( static_cast<ui::DomCode>(dom_code))); diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index f495739..af21587 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h @@ -34,6 +34,7 @@ class MessageLoop; namespace content { class FlingCurveConfiguration; class NotificationDispatcher; +class PermissionManager; class PushDispatcher; class ThreadSafeSender; class WebBluetoothImpl; @@ -157,6 +158,7 @@ class CONTENT_EXPORT BlinkPlatformImpl virtual blink::WebNotificationManager* notificationManager(); virtual blink::WebPushProvider* pushProvider(); virtual blink::WebNavigatorConnectProvider* navigatorConnectProvider(); + virtual blink::WebPermissionClient* permissionClient(); void SuspendSharedTimer(); void ResumeSharedTimer(); @@ -176,6 +178,8 @@ class CONTENT_EXPORT BlinkPlatformImpl void InternalInit(); void UpdateWebThreadTLS(blink::WebThread* thread); + bool IsMainThread() const; + scoped_refptr<base::SingleThreadTaskRunner> MainTaskRunnerForCurrentThread(); scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; @@ -194,6 +198,7 @@ class CONTENT_EXPORT BlinkPlatformImpl scoped_refptr<ThreadSafeSender> thread_safe_sender_; scoped_refptr<NotificationDispatcher> notification_dispatcher_; scoped_refptr<PushDispatcher> push_dispatcher_; + scoped_ptr<PermissionManager> permission_client_; }; } // namespace content diff --git a/content/child/permissions/OWNERS b/content/child/permissions/OWNERS new file mode 100644 index 0000000..2d28246 --- /dev/null +++ b/content/child/permissions/OWNERS @@ -0,0 +1 @@ +mlamouri@chromium.org diff --git a/content/child/permissions/permission_manager.cc b/content/child/permissions/permission_manager.cc new file mode 100644 index 0000000..d7e1f2c --- /dev/null +++ b/content/child/permissions/permission_manager.cc @@ -0,0 +1,155 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/child/permissions/permission_manager.h" + +#include "content/child/worker_task_runner.h" +#include "content/public/common/service_registry.h" +#include "third_party/WebKit/public/platform/WebURL.h" + +namespace content { + +namespace { + +PermissionName GetPermissionName(blink::WebPermissionType type) { + switch (type) { + case blink::WebPermissionTypeGeolocation: + return PERMISSION_NAME_GEOLOCATION; + case blink::WebPermissionTypeNotifications: + return PERMISSION_NAME_NOTIFICATIONS; + case blink::WebPermissionTypePushNotifications: + return PERMISSION_NAME_PUSH_NOTIFICATIONS; + case blink::WebPermissionTypeMidiSysEx: + return PERMISSION_NAME_MIDI_SYSEX; + default: + // The default statement is only there to prevent compilation failures if + // WebPermissionType enum gets extended. + NOTREACHED(); + return PERMISSION_NAME_GEOLOCATION; + } +} + +blink::WebPermissionStatus GetWebPermissionStatus(PermissionStatus status) { + switch (status) { + case PERMISSION_STATUS_GRANTED: + return blink::WebPermissionStatusGranted; + case PERMISSION_STATUS_DENIED: + return blink::WebPermissionStatusDenied; + case PERMISSION_STATUS_ASK: + return blink::WebPermissionStatusPrompt; + } + + NOTREACHED(); + return blink::WebPermissionStatusDenied; +} + +const int kNoWorkerThread = 0; + +} // anonymous namespace + +PermissionManager::CallbackInformation::CallbackInformation( + blink::WebPermissionQueryCallback* callback, + int worker_thread_id) + : callback_(callback), + worker_thread_id_(worker_thread_id) { +} + +blink::WebPermissionQueryCallback* +PermissionManager::CallbackInformation::callback() const { + return callback_.get(); +} + +int PermissionManager::CallbackInformation::worker_thread_id() const { + return worker_thread_id_; +} + +blink::WebPermissionQueryCallback* +PermissionManager::CallbackInformation::ReleaseCallback() { + return callback_.release(); +} + +PermissionManager::CallbackInformation::~CallbackInformation() { +} + +PermissionManager::PermissionManager(ServiceRegistry* service_registry) + : service_registry_(service_registry) { +} + +PermissionManager::~PermissionManager() { +} + +void PermissionManager::queryPermission( + blink::WebPermissionType type, + const blink::WebURL& origin, + blink::WebPermissionQueryCallback* callback) { + QueryPermissionInternal( + type, origin.string().utf8(), callback, kNoWorkerThread); +} + +void PermissionManager::QueryPermissionForWorker( + blink::WebPermissionType type, + const std::string& origin, + blink::WebPermissionQueryCallback* callback, + int worker_thread_id) { + QueryPermissionInternal(type, origin, callback, worker_thread_id); +} + +void PermissionManager::QueryPermissionInternal( + blink::WebPermissionType type, + const std::string& origin, + blink::WebPermissionQueryCallback* callback, + int worker_thread_id) { + // We need to save the |callback| in an IDMap so if |this| gets deleted, the + // callback will not leak. In the case of |this| gets deleted, the + // |permission_service_| pipe will be destroyed too so OnQueryPermission will + // not be called. + int request_id = pending_callbacks_.Add( + new CallbackInformation(callback, worker_thread_id)); + if (!permission_service_.get()) + service_registry_->ConnectToRemoteService(&permission_service_); + permission_service_->HasPermission( + GetPermissionName(type), + origin, + base::Bind(&PermissionManager::OnQueryPermission, + base::Unretained(this), + request_id)); +} + +void PermissionManager::OnQueryPermission(int request_id, + PermissionStatus result) { + CallbackInformation* callback_information = + pending_callbacks_.Lookup(request_id); + DCHECK(callback_information && callback_information->callback()); + scoped_ptr<blink::WebPermissionStatus> status( + new blink::WebPermissionStatus(GetWebPermissionStatus(result))); + + if (callback_information->worker_thread_id() != kNoWorkerThread) { + blink::WebPermissionQueryCallback* callback = + callback_information->ReleaseCallback(); + int worker_thread_id = callback_information->worker_thread_id(); + pending_callbacks_.Remove(request_id); + + // If the worker is no longer running, ::PostTask() will return false and + // gracefully fail, destroying the callback too. + WorkerTaskRunner::Instance()->PostTask( + worker_thread_id, + base::Bind(&PermissionManager::RunCallbackOnWorkerThread, + base::Unretained(callback), + base::Passed(&status))); + return; + } + + callback_information->callback()->onSuccess(status.release()); + pending_callbacks_.Remove(request_id); +} + +// static +void PermissionManager::RunCallbackOnWorkerThread( + blink::WebPermissionQueryCallback* callback, + scoped_ptr<blink::WebPermissionStatus> status) { + callback->onSuccess(status.release()); + delete callback; +} + +} // namespace content diff --git a/content/child/permissions/permission_manager.h b/content/child/permissions/permission_manager.h new file mode 100644 index 0000000..b445e90 --- /dev/null +++ b/content/child/permissions/permission_manager.h @@ -0,0 +1,87 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_CHILD_PERMISSIONS_PERMISSION_MANAGER_H_ +#define CONTENT_CHILD_PERMISSIONS_PERMISSION_MANAGER_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/id_map.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "content/common/permission_service.mojom.h" +#include "third_party/WebKit/public/platform/modules/permissions/WebPermissionClient.h" + +namespace content { + +class ServiceRegistry; + +// The PermissionManager is a layer between Blink and the Mojo PermissionService +// It implements blink::WebPermissionClient. It is being used from workers and +// frames independently. When called outside of the main thread, +// QueryPermissionForWorker is meant to be called. It will handle the thread +// jumping. +class PermissionManager : public blink::WebPermissionClient { + public: + // The caller must guarantee that |service_registry| will have a lifetime + // larger than this instance of PermissionManager. + explicit PermissionManager(ServiceRegistry* service_registry); + virtual ~PermissionManager(); + + // blink::WebPermissionClient implementation. + virtual void queryPermission(blink::WebPermissionType type, + const blink::WebURL& origin, + blink::WebPermissionQueryCallback* callback); + + void QueryPermissionForWorker(blink::WebPermissionType type, + const std::string& origin, + blink::WebPermissionQueryCallback* callback, + int worker_thread_id); + + protected: + void QueryPermissionInternal(blink::WebPermissionType type, + const std::string& origin, + blink::WebPermissionQueryCallback* callback, + int worker_thread_id); + + void OnQueryPermission(int request_id, PermissionStatus status); + + // Called from the main thread in order to run the callback in the thread it + // was created on. + static void RunCallbackOnWorkerThread( + blink::WebPermissionQueryCallback* callback, + scoped_ptr<blink::WebPermissionStatus> status); + + // Saves some basic information about the callback in order to be able to run + // it in the right thread. + class CallbackInformation { + public: + CallbackInformation(blink::WebPermissionQueryCallback* callback, + int worker_thread_id); + ~CallbackInformation(); + + blink::WebPermissionQueryCallback* callback() const; + int worker_thread_id() const; + + blink::WebPermissionQueryCallback* ReleaseCallback(); + + private: + scoped_ptr<blink::WebPermissionQueryCallback> callback_; + int worker_thread_id_; + + DISALLOW_COPY_AND_ASSIGN(CallbackInformation); + }; + using CallbackMap = IDMap<CallbackInformation, IDMapOwnPointer>; + CallbackMap pending_callbacks_; + + ServiceRegistry* service_registry_; + PermissionServicePtr permission_service_; + + DISALLOW_COPY_AND_ASSIGN(PermissionManager); +}; + +} // namespace content + +#endif // CONTENT_CHILD_PERMISSIONS_PERMISSION_MANAGER_H_ diff --git a/content/child/permissions/permission_manager_thread_proxy.cc b/content/child/permissions/permission_manager_thread_proxy.cc new file mode 100644 index 0000000..8af0f23 --- /dev/null +++ b/content/child/permissions/permission_manager_thread_proxy.cc @@ -0,0 +1,74 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/child/permissions/permission_manager_thread_proxy.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/lazy_instance.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_local.h" +#include "content/child/permissions/permission_manager.h" +#include "content/child/worker_task_runner.h" +#include "third_party/WebKit/public/platform/WebURL.h" + +using base::LazyInstance; +using base::ThreadLocalPointer; + +namespace content { + +namespace { + +LazyInstance<ThreadLocalPointer<PermissionManagerThreadProxy>>::Leaky + g_permission_manager_tls = LAZY_INSTANCE_INITIALIZER; + +} // anonymous namespace + +PermissionManagerThreadProxy* +PermissionManagerThreadProxy::GetThreadInstance( + base::SingleThreadTaskRunner* main_thread_task_runner, + PermissionManager* permissions_manager) { + if (g_permission_manager_tls.Pointer()->Get()) + return g_permission_manager_tls.Pointer()->Get(); + + PermissionManagerThreadProxy* instance = + new PermissionManagerThreadProxy(main_thread_task_runner, + permissions_manager); + DCHECK(WorkerTaskRunner::Instance()->CurrentWorkerId()); + WorkerTaskRunner::Instance()->AddStopObserver(instance); + return instance; +} + +PermissionManagerThreadProxy::PermissionManagerThreadProxy( + base::SingleThreadTaskRunner* main_thread_task_runner, + PermissionManager* permissions_manager) + : main_thread_task_runner_(main_thread_task_runner), + permissions_manager_(permissions_manager) { + g_permission_manager_tls.Pointer()->Set(this); +} + +PermissionManagerThreadProxy::~PermissionManagerThreadProxy() { + g_permission_manager_tls.Pointer()->Set(nullptr); +} + +void PermissionManagerThreadProxy::queryPermission( + blink::WebPermissionType type, + const blink::WebURL& origin, + blink::WebPermissionQueryCallback* callback) { + main_thread_task_runner_->PostTask( + FROM_HERE, + base::Bind(&PermissionManager::QueryPermissionForWorker, + base::Unretained(permissions_manager_), + type, + origin.string().utf8(), + base::Unretained(callback), + WorkerTaskRunner::Instance()->CurrentWorkerId())); +} + +void PermissionManagerThreadProxy::OnWorkerRunLoopStopped() { + delete this; +} + +} // namespace content diff --git a/content/child/permissions/permission_manager_thread_proxy.h b/content/child/permissions/permission_manager_thread_proxy.h new file mode 100644 index 0000000..b67fe98 --- /dev/null +++ b/content/child/permissions/permission_manager_thread_proxy.h @@ -0,0 +1,54 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_CHILD_PERMISSIONS_PERMISSION_MANAGER_THREAD_PROXY_H_ +#define CONTENT_CHILD_PERMISSIONS_PERMISSION_MANAGER_THREAD_PROXY_H_ + +#include "base/compiler_specific.h" +#include "base/id_map.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "content/child/worker_task_runner.h" +#include "third_party/WebKit/public/platform/modules/permissions/WebPermissionClient.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace content { + +class PermissionManager; + +class PermissionManagerThreadProxy : + public blink::WebPermissionClient, + public WorkerTaskRunner::Observer { + public: + static PermissionManagerThreadProxy* GetThreadInstance( + base::SingleThreadTaskRunner* main_thread_task_runner, + PermissionManager* permissions_manager); + + // blink::WebPermissionClient implementation. + virtual void queryPermission(blink::WebPermissionType type, + const blink::WebURL& origin, + blink::WebPermissionQueryCallback* callback); + + // WorkerTaskRunner::Observer implementation. + void OnWorkerRunLoopStopped() override; + + private: + PermissionManagerThreadProxy( + base::SingleThreadTaskRunner* main_thread_task_runner, + PermissionManager* permissions_manager); + + virtual ~PermissionManagerThreadProxy(); + + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + PermissionManager* permissions_manager_; + + DISALLOW_COPY_AND_ASSIGN(PermissionManagerThreadProxy); +}; + +} // namespace content + +#endif // CONTENT_CHILD_PERMISSIONS_PERMISSIONS_MANAGER_THREAD_PROXY_H_ diff --git a/content/common/permission_service.mojom b/content/common/permission_service.mojom index 9dd952d..2ed9d3e 100644 --- a/content/common/permission_service.mojom +++ b/content/common/permission_service.mojom @@ -8,8 +8,9 @@ import "content/public/common/permission_status.mojom"; enum PermissionName { GEOLOCATION, - MIDI_SYSEX, NOTIFICATIONS, + PUSH_NOTIFICATIONS, + MIDI_SYSEX, PROTECTED_MEDIA_IDENTIFIER, }; diff --git a/content/content_child.gypi b/content/content_child.gypi index 1f11446..bb329b0 100644 --- a/content/content_child.gypi +++ b/content/content_child.gypi @@ -163,6 +163,10 @@ 'child/npapi/webplugin_ime_win.cc', 'child/npapi/webplugin_ime_win.h', 'child/npapi/webplugin_resource_client.h', + 'child/permissions/permission_manager.cc', + 'child/permissions/permission_manager.h', + 'child/permissions/permission_manager_thread_proxy.cc', + 'child/permissions/permission_manager_thread_proxy.h', 'child/plugin_message_generator.cc', 'child/plugin_message_generator.h', 'child/plugin_messages.h', diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 7d24ae9..eaf627c 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -21,6 +21,7 @@ #include "base/time/time.h" #include "cc/base/switches.h" #include "content/child/appcache/appcache_dispatcher.h" +#include "content/child/permissions/permission_manager.h" #include "content/child/plugin_messages.h" #include "content/child/quota_dispatcher.h" #include "content/child/request_extra_data.h" @@ -3657,6 +3658,13 @@ void RenderFrameImpl::suddenTerminationDisablerChanged( } } +blink::WebPermissionClient* RenderFrameImpl::permissionClient() { + if (!permission_client_) + permission_client_.reset(new PermissionManager(GetServiceRegistry())); + + return permission_client_.get(); +} + void RenderFrameImpl::DidPlay(blink::WebMediaPlayer* player) { Send(new FrameHostMsg_MediaPlayingNotification( routing_id_, reinterpret_cast<int64>(player), player->hasVideo(), diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 6a3daa7..77b19ae 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h @@ -84,6 +84,7 @@ class MidiDispatcher; class NotificationPermissionDispatcher; class PageState; class PepperPluginInstanceImpl; +class PermissionManager; class PresentationDispatcher; class PushMessagingDispatcher; class RendererAccessibility; @@ -518,9 +519,10 @@ class CONTENT_EXPORT RenderFrameImpl virtual void didChangeDefaultPresentation(blink::WebLocalFrame*); virtual bool enterFullscreen(); virtual bool exitFullscreen(); - void suddenTerminationDisablerChanged( + virtual void suddenTerminationDisablerChanged( bool present, - blink::WebFrameClient::SuddenTerminationDisablerType type) override; + blink::WebFrameClient::SuddenTerminationDisablerType type); + virtual blink::WebPermissionClient* permissionClient(); // WebMediaPlayerDelegate implementation: void DidPlay(blink::WebMediaPlayer* player) override; @@ -878,6 +880,8 @@ class CONTENT_EXPORT RenderFrameImpl // AccessibilityModeOff. RendererAccessibility* renderer_accessibility_; + scoped_ptr<PermissionManager> permission_client_; + #if defined(OS_MACOSX) || defined(OS_ANDROID) // The external popup for the currently showing select popup. scoped_ptr<ExternalPopupMenu> external_popup_menu_; |