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. 4 5 #include "content/shell/renderer/test_runner/gamepad_controller.h" 6 7 #include "content/shell/renderer/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" 16 17 using blink::WebFrame; 18 using blink::WebGamepad; 19 using blink::WebGamepads; 20 21 namespace content { 22 23 class GamepadControllerBindings 24 : public gin::Wrappable<GamepadControllerBindings> { 25 public: 26 static gin::WrapperInfo kWrapperInfo; 27 28 static void Install(base::WeakPtr<GamepadController> controller, 29 blink::WebFrame* frame); 30 31 private: 32 explicit GamepadControllerBindings( 33 base::WeakPtr<GamepadController> controller); 34 virtual ~GamepadControllerBindings(); 35 36 // gin::Wrappable. 37 virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder( 38 v8::Isolate* isolate) OVERRIDE; 39 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); 48 49 base::WeakPtr<GamepadController> controller_; 50 51 DISALLOW_COPY_AND_ASSIGN(GamepadControllerBindings); 52 }; 53 54 gin::WrapperInfo GamepadControllerBindings::kWrapperInfo = { 55 gin::kEmbedderNativeGin}; 56 57 // static 58 void GamepadControllerBindings::Install( 59 base::WeakPtr<GamepadController> controller, 60 WebFrame* frame) { 61 v8::Isolate* isolate = blink::mainThreadIsolate(); 62 v8::HandleScope handle_scope(isolate); 63 v8::Handle<v8::Context> context = frame->mainWorldScriptContext(); 64 if (context.IsEmpty()) 65 return; 66 67 v8::Context::Scope context_scope(context); 68 69 gin::Handle<GamepadControllerBindings> bindings = 70 gin::CreateHandle(isolate, new GamepadControllerBindings(controller)); 71 if (bindings.IsEmpty()) 72 return; 73 v8::Handle<v8::Object> global = context->Global(); 74 global->Set(gin::StringToV8(isolate, "gamepadController"), bindings.ToV8()); 75 } 76 77 GamepadControllerBindings::GamepadControllerBindings( 78 base::WeakPtr<GamepadController> controller) 79 : controller_(controller) {} 80 81 GamepadControllerBindings::~GamepadControllerBindings() {} 82 83 gin::ObjectTemplateBuilder GamepadControllerBindings::GetObjectTemplateBuilder( 84 v8::Isolate* isolate) { 85 return gin::Wrappable<GamepadControllerBindings>::GetObjectTemplateBuilder( 86 isolate) 87 .SetMethod("connect", &GamepadControllerBindings::Connect) 88 .SetMethod("dispatchConnected", &GamepadControllerBindings::DispatchConnected) 89 .SetMethod("disconnect", &GamepadControllerBindings::Disconnect) 90 .SetMethod("setId", &GamepadControllerBindings::SetId) 91 .SetMethod("setButtonCount", &GamepadControllerBindings::SetButtonCount) 92 .SetMethod("setButtonData", &GamepadControllerBindings::SetButtonData) 93 .SetMethod("setAxisCount", &GamepadControllerBindings::SetAxisCount) 94 .SetMethod("setAxisData", &GamepadControllerBindings::SetAxisData); 95 } 96 97 void GamepadControllerBindings::Connect(int index) { 98 if (controller_) 99 controller_->Connect(index); 100 } 101 102 void GamepadControllerBindings::DispatchConnected(int index) { 103 if (controller_) 104 controller_->DispatchConnected(index); 105 } 106 107 void GamepadControllerBindings::Disconnect(int index) { 108 if (controller_) 109 controller_->Disconnect(index); 110 } 111 112 void GamepadControllerBindings::SetId(int index, const std::string& src) { 113 if (controller_) 114 controller_->SetId(index, src); 115 } 116 117 void GamepadControllerBindings::SetButtonCount(int index, int buttons) { 118 if (controller_) 119 controller_->SetButtonCount(index, buttons); 120 } 121 122 void GamepadControllerBindings::SetButtonData(int index, 123 int button, 124 double data) { 125 if (controller_) 126 controller_->SetButtonData(index, button, data); 127 } 128 129 void GamepadControllerBindings::SetAxisCount(int index, int axes) { 130 if (controller_) 131 controller_->SetAxisCount(index, axes); 132 } 133 134 void GamepadControllerBindings::SetAxisData(int index, int axis, double data) { 135 if (controller_) 136 controller_->SetAxisData(index, axis, data); 137 } 138 139 // static 140 base::WeakPtr<GamepadController> GamepadController::Create(WebTestDelegate* delegate) { 141 CHECK(delegate); 142 143 GamepadController* controller = new GamepadController(); 144 delegate->SetGamepadProvider(scoped_ptr<RendererGamepadProvider>(controller)); 145 return controller->weak_factory_.GetWeakPtr(); 146 } 147 148 GamepadController::GamepadController() 149 : RendererGamepadProvider(0), 150 weak_factory_(this) { 151 Reset(); 152 } 153 154 GamepadController::~GamepadController() {} 155 156 void GamepadController::Reset() { 157 memset(&gamepads_, 0, sizeof(gamepads_)); 158 } 159 160 void GamepadController::Install(WebFrame* frame) { 161 GamepadControllerBindings::Install(weak_factory_.GetWeakPtr(), frame); 162 } 163 164 165 void GamepadController::SampleGamepads(blink::WebGamepads& gamepads) { 166 memcpy(&gamepads, &gamepads_, sizeof(blink::WebGamepads)); 167 } 168 169 bool GamepadController::OnControlMessageReceived(const IPC::Message& msg) { 170 return false; 171 } 172 173 void GamepadController::SendStartMessage() { 174 } 175 176 void GamepadController::SendStopMessage() { 177 } 178 179 void GamepadController::Connect(int index) { 180 if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) 181 return; 182 gamepads_.items[index].connected = true; 183 gamepads_.length = 0; 184 for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { 185 if (gamepads_.items[i].connected) 186 gamepads_.length = i + 1; 187 } 188 } 189 190 void GamepadController::DispatchConnected(int index) { 191 if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap) 192 || !gamepads_.items[index].connected) 193 return; 194 const WebGamepad& pad = gamepads_.items[index]; 195 if (listener()) 196 listener()->didConnectGamepad(index, pad); 197 } 198 199 void GamepadController::Disconnect(int index) { 200 if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) 201 return; 202 WebGamepad& pad = gamepads_.items[index]; 203 pad.connected = false; 204 gamepads_.length = 0; 205 for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { 206 if (gamepads_.items[i].connected) 207 gamepads_.length = i + 1; 208 } 209 if (listener()) 210 listener()->didDisconnectGamepad(index, pad); 211 } 212 213 void GamepadController::SetId(int index, const std::string& src) { 214 if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) 215 return; 216 const char* p = src.c_str(); 217 memset(gamepads_.items[index].id, 0, sizeof(gamepads_.items[index].id)); 218 for (unsigned i = 0; *p && i < WebGamepad::idLengthCap - 1; ++i) 219 gamepads_.items[index].id[i] = *p++; 220 } 221 222 void GamepadController::SetButtonCount(int index, int buttons) { 223 if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) 224 return; 225 if (buttons < 0 || buttons >= static_cast<int>(WebGamepad::buttonsLengthCap)) 226 return; 227 gamepads_.items[index].buttonsLength = buttons; 228 } 229 230 void GamepadController::SetButtonData(int index, int button, double data) { 231 if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) 232 return; 233 if (button < 0 || button >= static_cast<int>(WebGamepad::buttonsLengthCap)) 234 return; 235 gamepads_.items[index].buttons[button].value = data; 236 gamepads_.items[index].buttons[button].pressed = data > 0.1f; 237 } 238 239 void GamepadController::SetAxisCount(int index, int axes) { 240 if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) 241 return; 242 if (axes < 0 || axes >= static_cast<int>(WebGamepad::axesLengthCap)) 243 return; 244 gamepads_.items[index].axesLength = axes; 245 } 246 247 void GamepadController::SetAxisData(int index, int axis, double data) { 248 if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) 249 return; 250 if (axis < 0 || axis >= static_cast<int>(WebGamepad::axesLengthCap)) 251 return; 252 gamepads_.items[index].axes[axis] = data; 253 } 254 255 } // namespace content 256