15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_SERVICE_H 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_SERVICE_H 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <set> 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_checker.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/content_export.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace blink { 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class WebGamepad; 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class GamepadConsumer; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GamepadDataFetcher; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GamepadProvider; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GamepadServiceTestConstructor; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderProcessHost; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Owns the GamepadProvider (the background polling thread) and keeps track of 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the number of consumers currently using the data (and pausing the provider 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when not in use). 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CONTENT_EXPORT GamepadService { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the GamepadService singleton. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static GamepadService* GetInstance(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Increments the number of users of the provider. The Provider is running 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when there's > 0 users, and is paused when the count drops to 0. 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // consumer is registered to listen for gamepad connections. If this is the 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // first time it is added to the set of consumers it will be treated 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // specially: it will not be informed about connections before a new user 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // gesture is observed at which point it will be notified for every connected 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // gamepads. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must be called on the I/O thread. 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void ConsumerBecameActive(GamepadConsumer* consumer); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Decrements the number of users of the provider. consumer will not be 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // informed about connections until it's added back via ConsumerBecameActive. 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Must be matched with a ConsumerBecameActive call. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must be called on the I/O thread. 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void ConsumerBecameInactive(GamepadConsumer* consumer); 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Decrements the number of users of the provider and removes consumer from 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the set of consumers. Should be matched with a a ConsumerBecameActive 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // call. 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Must be called on the I/O thread. 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void RemoveConsumer(GamepadConsumer* consumer); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Registers the given closure for calling when the user has interacted with 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the device. This callback will only be issued once. Should only be called 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // while a consumer is active. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RegisterForUserGesture(const base::Closure& closure); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the shared memory handle of the gamepad data duplicated into the 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // given process. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle GetSharedMemoryHandleForProcess( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle handle); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop/join with the background thread in GamepadProvider |provider_|. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Terminate(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Called on IO thread when a gamepad is connected. 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void OnGamepadConnected(int index, const blink::WebGamepad& pad); 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Called on IO thread when a gamepad is disconnected. 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void OnGamepadDisconnected(int index, const blink::WebGamepad& pad); 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct DefaultSingletonTraits<GamepadService>; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class GamepadServiceTestConstructor; 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch friend class GamepadServiceTest; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GamepadService(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constructor for testing. This specifies the data fetcher to use for a 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provider, bypassing the default platform one. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GamepadService(scoped_ptr<GamepadDataFetcher> fetcher); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~GamepadService(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static void SetInstance(GamepadService*); 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void OnUserGesture(); 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) struct ConsumerInfo { 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConsumerInfo(GamepadConsumer* consumer) 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : consumer(consumer), 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) did_observe_user_gesture(false) { 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool operator<(const ConsumerInfo& other) const { 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return consumer < other.consumer; 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GamepadConsumer* consumer; 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mutable bool is_active; 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mutable bool did_observe_user_gesture; 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<GamepadProvider> provider_; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadChecker thread_checker_; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) typedef std::set<ConsumerInfo> ConsumerSet; 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConsumerSet consumers_; 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int num_active_consumers_; 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool gesture_callback_pending_; 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GamepadService); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CONTENT_BROWSER_GAMEPAD_GAMEPAD_SERVICE_H_ 131