1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/gamepad/gamepad_service.h"
8 #include "base/logging.h"
9 #include "base/memory/singleton.h"
10 #include "content/browser/gamepad/gamepad_consumer.h"
11 #include "content/browser/gamepad/gamepad_data_fetcher.h"
12 #include "content/browser/gamepad/gamepad_provider.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/render_process_host.h"
18 GamepadService::GamepadService()
19 : num_active_consumers_(0),
20 gesture_callback_pending_(false) {
23 GamepadService::GamepadService(scoped_ptr<GamepadDataFetcher> fetcher)
24 : provider_(new GamepadProvider(fetcher.Pass())),
25 num_active_consumers_(0),
26 gesture_callback_pending_(false) {
27 thread_checker_.DetachFromThread();
30 GamepadService::~GamepadService() {
33 GamepadService* GamepadService::GetInstance() {
34 return Singleton<GamepadService,
35 LeakySingletonTraits<GamepadService> >::get();
38 void GamepadService::ConsumerBecameActive(GamepadConsumer* consumer) {
39 DCHECK(thread_checker_.CalledOnValidThread());
42 provider_.reset(new GamepadProvider);
44 std::pair<ConsumerSet::iterator, bool> insert_result =
45 consumers_.insert(consumer);
46 insert_result.first->is_active = true;
47 if (!insert_result.first->did_observe_user_gesture &&
48 !gesture_callback_pending_) {
49 provider_->RegisterForUserGesture(
50 base::Bind(&GamepadService::OnUserGesture,
51 base::Unretained(this)));
54 if (num_active_consumers_++ == 0)
58 void GamepadService::ConsumerBecameInactive(GamepadConsumer* consumer) {
60 DCHECK(num_active_consumers_ > 0);
61 DCHECK(consumers_.count(consumer) > 0);
62 DCHECK(consumers_.find(consumer)->is_active);
64 consumers_.find(consumer)->is_active = false;
65 if (--num_active_consumers_ == 0)
69 void GamepadService::RemoveConsumer(GamepadConsumer* consumer) {
70 DCHECK(thread_checker_.CalledOnValidThread());
72 ConsumerSet::iterator it = consumers_.find(consumer);
73 if (it->is_active && --num_active_consumers_ == 0)
78 void GamepadService::RegisterForUserGesture(const base::Closure& closure) {
79 DCHECK(consumers_.size() > 0);
80 DCHECK(thread_checker_.CalledOnValidThread());
81 provider_->RegisterForUserGesture(closure);
84 void GamepadService::Terminate() {
88 void GamepadService::OnGamepadConnected(
90 const blink::WebGamepad& pad) {
91 DCHECK(thread_checker_.CalledOnValidThread());
93 for (ConsumerSet::iterator it = consumers_.begin();
94 it != consumers_.end(); ++it) {
95 if (it->did_observe_user_gesture && it->is_active)
96 it->consumer->OnGamepadConnected(index, pad);
100 void GamepadService::OnGamepadDisconnected(
102 const blink::WebGamepad& pad) {
103 DCHECK(thread_checker_.CalledOnValidThread());
105 for (ConsumerSet::iterator it = consumers_.begin();
106 it != consumers_.end(); ++it) {
107 if (it->did_observe_user_gesture && it->is_active)
108 it->consumer->OnGamepadDisconnected(index, pad);
112 base::SharedMemoryHandle GamepadService::GetSharedMemoryHandleForProcess(
113 base::ProcessHandle handle) {
114 DCHECK(thread_checker_.CalledOnValidThread());
115 return provider_->GetSharedMemoryHandleForProcess(handle);
118 void GamepadService::OnUserGesture() {
119 DCHECK(thread_checker_.CalledOnValidThread());
121 gesture_callback_pending_ = false;
124 num_active_consumers_ == 0)
127 for (ConsumerSet::iterator it = consumers_.begin();
128 it != consumers_.end(); ++it) {
129 if (!it->did_observe_user_gesture && it->is_active) {
130 const ConsumerInfo& info = *it;
131 info.did_observe_user_gesture = true;
132 blink::WebGamepads gamepads;
133 provider_->GetCurrentGamepadData(&gamepads);
134 for (unsigned i = 0; i < blink::WebGamepads::itemsLengthCap; ++i) {
135 const blink::WebGamepad& pad = gamepads.items[i];
137 info.consumer->OnGamepadConnected(i, pad);
143 } // namespace content