1 // Copyright 2014 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 "components/test_runner/gamepad_controller.h"
7 #include "components/test_runner/web_test_delegate.h"
8 #include "gin/arguments.h"
9 #include "gin/handle.h"
10 #include "gin/object_template_builder.h"
11 #include "gin/wrappable.h"
12 #include "third_party/WebKit/public/platform/WebGamepadListener.h"
13 #include "third_party/WebKit/public/web/WebFrame.h"
14 #include "third_party/WebKit/public/web/WebKit.h"
15 #include "v8/include/v8.h"
17 using blink::WebFrame
;
18 using blink::WebGamepad
;
19 using blink::WebGamepads
;
21 namespace test_runner
{
23 class GamepadControllerBindings
24 : public gin::Wrappable
<GamepadControllerBindings
> {
26 static gin::WrapperInfo kWrapperInfo
;
28 static void Install(base::WeakPtr
<GamepadController
> controller
,
29 blink::WebFrame
* frame
);
32 explicit GamepadControllerBindings(
33 base::WeakPtr
<GamepadController
> controller
);
34 ~GamepadControllerBindings() override
;
37 gin::ObjectTemplateBuilder
GetObjectTemplateBuilder(
38 v8::Isolate
* isolate
) override
;
40 void Connect(int index
);
41 void DispatchConnected(int index
);
42 void Disconnect(int index
);
43 void SetId(int index
, const std::string
& src
);
44 void SetButtonCount(int index
, int buttons
);
45 void SetButtonData(int index
, int button
, double data
);
46 void SetAxisCount(int index
, int axes
);
47 void SetAxisData(int index
, int axis
, double data
);
49 base::WeakPtr
<GamepadController
> controller_
;
51 DISALLOW_COPY_AND_ASSIGN(GamepadControllerBindings
);
54 gin::WrapperInfo
GamepadControllerBindings::kWrapperInfo
= {
55 gin::kEmbedderNativeGin
};
58 void GamepadControllerBindings::Install(
59 base::WeakPtr
<GamepadController
> controller
,
61 v8::Isolate
* isolate
= blink::mainThreadIsolate();
62 v8::HandleScope
handle_scope(isolate
);
63 v8::Local
<v8::Context
> context
= frame
->mainWorldScriptContext();
64 if (context
.IsEmpty())
67 v8::Context::Scope
context_scope(context
);
69 gin::Handle
<GamepadControllerBindings
> bindings
=
70 gin::CreateHandle(isolate
, new GamepadControllerBindings(controller
));
71 if (bindings
.IsEmpty())
73 v8::Local
<v8::Object
> global
= context
->Global();
74 global
->Set(gin::StringToV8(isolate
, "gamepadController"), bindings
.ToV8());
77 GamepadControllerBindings::GamepadControllerBindings(
78 base::WeakPtr
<GamepadController
> controller
)
79 : controller_(controller
) {}
81 GamepadControllerBindings::~GamepadControllerBindings() {}
83 gin::ObjectTemplateBuilder
GamepadControllerBindings::GetObjectTemplateBuilder(
84 v8::Isolate
* isolate
) {
85 return gin::Wrappable
<GamepadControllerBindings
>::GetObjectTemplateBuilder(
87 .SetMethod("connect", &GamepadControllerBindings::Connect
)
88 .SetMethod("dispatchConnected",
89 &GamepadControllerBindings::DispatchConnected
)
90 .SetMethod("disconnect", &GamepadControllerBindings::Disconnect
)
91 .SetMethod("setId", &GamepadControllerBindings::SetId
)
92 .SetMethod("setButtonCount", &GamepadControllerBindings::SetButtonCount
)
93 .SetMethod("setButtonData", &GamepadControllerBindings::SetButtonData
)
94 .SetMethod("setAxisCount", &GamepadControllerBindings::SetAxisCount
)
95 .SetMethod("setAxisData", &GamepadControllerBindings::SetAxisData
);
98 void GamepadControllerBindings::Connect(int index
) {
100 controller_
->Connect(index
);
103 void GamepadControllerBindings::DispatchConnected(int index
) {
105 controller_
->DispatchConnected(index
);
108 void GamepadControllerBindings::Disconnect(int index
) {
110 controller_
->Disconnect(index
);
113 void GamepadControllerBindings::SetId(int index
, const std::string
& src
) {
115 controller_
->SetId(index
, src
);
118 void GamepadControllerBindings::SetButtonCount(int index
, int buttons
) {
120 controller_
->SetButtonCount(index
, buttons
);
123 void GamepadControllerBindings::SetButtonData(int index
,
127 controller_
->SetButtonData(index
, button
, data
);
130 void GamepadControllerBindings::SetAxisCount(int index
, int axes
) {
132 controller_
->SetAxisCount(index
, axes
);
135 void GamepadControllerBindings::SetAxisData(int index
, int axis
, double data
) {
137 controller_
->SetAxisData(index
, axis
, data
);
141 base::WeakPtr
<GamepadController
> GamepadController::Create(
142 WebTestDelegate
* delegate
) {
145 GamepadController
* controller
= new GamepadController();
146 delegate
->SetGamepadProvider(controller
);
147 return controller
->weak_factory_
.GetWeakPtr();
150 GamepadController::GamepadController()
151 : listener_(nullptr), weak_factory_(this) {
155 GamepadController::~GamepadController() {
158 void GamepadController::Reset() {
159 memset(&gamepads_
, 0, sizeof(gamepads_
));
162 void GamepadController::Install(WebFrame
* frame
) {
163 GamepadControllerBindings::Install(weak_factory_
.GetWeakPtr(), frame
);
166 void GamepadController::SampleGamepads(blink::WebGamepads
& gamepads
) {
167 memcpy(&gamepads
, &gamepads_
, sizeof(blink::WebGamepads
));
170 void GamepadController::SetListener(blink::WebGamepadListener
* listener
) {
171 listener_
= listener
;
174 void GamepadController::Connect(int index
) {
175 if (index
< 0 || index
>= static_cast<int>(WebGamepads::itemsLengthCap
))
177 gamepads_
.items
[index
].connected
= true;
178 gamepads_
.length
= 0;
179 for (unsigned i
= 0; i
< WebGamepads::itemsLengthCap
; ++i
) {
180 if (gamepads_
.items
[i
].connected
)
181 gamepads_
.length
= i
+ 1;
185 void GamepadController::DispatchConnected(int index
) {
186 if (index
< 0 || index
>= static_cast<int>(WebGamepads::itemsLengthCap
)
187 || !gamepads_
.items
[index
].connected
)
189 const WebGamepad
& pad
= gamepads_
.items
[index
];
191 listener_
->didConnectGamepad(index
, pad
);
194 void GamepadController::Disconnect(int index
) {
195 if (index
< 0 || index
>= static_cast<int>(WebGamepads::itemsLengthCap
))
197 WebGamepad
& pad
= gamepads_
.items
[index
];
198 pad
.connected
= false;
199 gamepads_
.length
= 0;
200 for (unsigned i
= 0; i
< WebGamepads::itemsLengthCap
; ++i
) {
201 if (gamepads_
.items
[i
].connected
)
202 gamepads_
.length
= i
+ 1;
205 listener_
->didDisconnectGamepad(index
, pad
);
208 void GamepadController::SetId(int index
, const std::string
& src
) {
209 if (index
< 0 || index
>= static_cast<int>(WebGamepads::itemsLengthCap
))
211 const char* p
= src
.c_str();
212 memset(gamepads_
.items
[index
].id
, 0, sizeof(gamepads_
.items
[index
].id
));
213 for (unsigned i
= 0; *p
&& i
< WebGamepad::idLengthCap
- 1; ++i
)
214 gamepads_
.items
[index
].id
[i
] = *p
++;
217 void GamepadController::SetButtonCount(int index
, int buttons
) {
218 if (index
< 0 || index
>= static_cast<int>(WebGamepads::itemsLengthCap
))
220 if (buttons
< 0 || buttons
>= static_cast<int>(WebGamepad::buttonsLengthCap
))
222 gamepads_
.items
[index
].buttonsLength
= buttons
;
225 void GamepadController::SetButtonData(int index
, int button
, double data
) {
226 if (index
< 0 || index
>= static_cast<int>(WebGamepads::itemsLengthCap
))
228 if (button
< 0 || button
>= static_cast<int>(WebGamepad::buttonsLengthCap
))
230 gamepads_
.items
[index
].buttons
[button
].value
= data
;
231 gamepads_
.items
[index
].buttons
[button
].pressed
= data
> 0.1f
;
234 void GamepadController::SetAxisCount(int index
, int axes
) {
235 if (index
< 0 || index
>= static_cast<int>(WebGamepads::itemsLengthCap
))
237 if (axes
< 0 || axes
>= static_cast<int>(WebGamepad::axesLengthCap
))
239 gamepads_
.items
[index
].axesLength
= axes
;
242 void GamepadController::SetAxisData(int index
, int axis
, double data
) {
243 if (index
< 0 || index
>= static_cast<int>(WebGamepads::itemsLengthCap
))
245 if (axis
< 0 || axis
>= static_cast<int>(WebGamepad::axesLengthCap
))
247 gamepads_
.items
[index
].axes
[axis
] = data
;
250 } // namespace test_runner