// 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_DISPATCHER_H_ #define CONTENT_CHILD_PERMISSIONS_PERMISSION_DISPATCHER_H_ #include #include "base/callback_forward.h" #include "base/id_map.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "content/child/permissions/permission_observers_registry.h" #include "content/common/permission_service.mojom.h" #include "third_party/WebKit/public/platform/modules/permissions/WebPermissionClient.h" namespace content { class ServiceRegistry; // The PermissionDispatcher 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 PermissionDispatcher : public blink::WebPermissionClient, public PermissionObserversRegistry { public: // Returns whether the given WebPermissionType is observable. Some types have // static values that never changes. static bool IsObservable(blink::WebPermissionType type); // The caller must guarantee that |service_registry| will have a lifetime // larger than this instance of PermissionDispatcher. explicit PermissionDispatcher(ServiceRegistry* service_registry); virtual ~PermissionDispatcher(); // blink::WebPermissionClient implementation. virtual void queryPermission(blink::WebPermissionType type, const blink::WebURL& origin, blink::WebPermissionQueryCallback* callback); virtual void startListening(blink::WebPermissionType type, const blink::WebURL& origin, blink::WebPermissionObserver* observer); virtual void stopListening(blink::WebPermissionObserver* observer); // The following methods must be called by workers on the main thread. void QueryPermissionForWorker(blink::WebPermissionType type, const std::string& origin, blink::WebPermissionQueryCallback* callback, int worker_thread_id); void StartListeningForWorker( blink::WebPermissionType type, const std::string& origin, int worker_thread_id, const base::Callback& callback); void GetNextPermissionChangeForWorker( blink::WebPermissionType type, const std::string& origin, blink::WebPermissionStatus status, int worker_thread_id, const base::Callback& callback); private: // Runs the given |callback| with |status| as a parameter. It has to be run // on a worker thread. static void RunCallbackOnWorkerThread( blink::WebPermissionQueryCallback* callback, scoped_ptr status); // Helper method that returns an initialized PermissionServicePtr. PermissionServicePtr& GetPermissionServicePtr(); void QueryPermissionInternal(blink::WebPermissionType type, const std::string& origin, blink::WebPermissionQueryCallback* callback, int worker_thread_id); void OnQueryPermission(int request_id, PermissionStatus status); void OnPermissionChanged(blink::WebPermissionType type, const std::string& origin, blink::WebPermissionObserver* observer, PermissionStatus status); void OnPermissionChangedForWorker( int worker_thread_id, const base::Callback& callback, PermissionStatus status); void GetNextPermissionChange(blink::WebPermissionType type, const std::string& origin, blink::WebPermissionObserver* observer, PermissionStatus current_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 callback_; int worker_thread_id_; DISALLOW_COPY_AND_ASSIGN(CallbackInformation); }; using CallbackMap = IDMap; CallbackMap pending_callbacks_; ServiceRegistry* service_registry_; PermissionServicePtr permission_service_; DISALLOW_COPY_AND_ASSIGN(PermissionDispatcher); }; } // namespace content #endif // CONTENT_CHILD_PERMISSIONS_PERMISSION_DISPATCHER_H_