OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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/renderer/gamepad_util.h" | |
6 | |
7 #include "base/debug/trace_event.h" | |
8 #include "base/metrics/histogram.h" | |
9 #include "content/common/gamepad_messages.h" | |
10 #include "content/public/renderer/render_thread.h" | |
11 #include "content/common/gamepad_hardware_buffer.h" | |
12 #include "ipc/ipc_sync_message_filter.h" | |
13 | |
14 using namespace content; | |
darin (slow to review)
2011/11/28 17:35:49
nit: the google c++ style guide forbids 'using nam
scottmg
2011/11/28 20:02:08
Done.
| |
15 using namespace gamepad; | |
16 | |
17 GamepadUtil::GamepadUtil() { | |
darin (slow to review)
2011/11/28 17:35:49
please come up with a better name for this class.
scottmg
2011/11/28 20:02:08
Done.
| |
18 memset(ever_interacted_with_, 0, sizeof(ever_interacted_with_)); | |
19 CHECK(RenderThread::Get()->Send(new GamepadHostMsg_StartPolling( | |
20 &renderer_shared_memory_handle_))); | |
21 renderer_shared_memory_.reset( | |
22 new base::SharedMemory(renderer_shared_memory_handle_, true)); | |
23 CHECK(renderer_shared_memory_->Map(sizeof(gamepad::GamepadHardwareBuffer))); | |
24 void *memory = renderer_shared_memory_->memory(); | |
25 CHECK(memory); | |
26 gamepad_hardware_buffer_ = static_cast<GamepadHardwareBuffer*>(memory); | |
27 } | |
28 | |
29 void GamepadUtil::SampleGamepads(WebKit::WebGamepads& gamepads) { | |
30 WebKit::WebGamepads read_into; | |
31 TRACE_EVENT0("GAMEPAD", "SampleGamepads"); | |
32 | |
33 // See gamepad_hardware_buffer.h for details on the read discipline. | |
34 base::subtle::Atomic32 start, end; | |
35 // Only try to read this many times before failing to avoid waiting here | |
36 // very long in case of contention with the writer. TODO(scottmg) Tune this | |
37 // number (as low as 1?) if histogram shows distribution as mostly | |
38 // 0-and-maximum. | |
39 const int maximum_contention_count = 10; | |
40 int contention_count = 0; | |
41 while (contention_count < maximum_contention_count) { | |
42 end = base::subtle::Acquire_Load(&gamepad_hardware_buffer_->end_marker); | |
darin (slow to review)
2011/11/28 17:35:49
i had expected to see a memory barrier here. i ad
scottmg
2011/11/28 20:02:08
I'm afraid that's probably a bug then. I thought I
| |
43 memcpy(&read_into, &gamepad_hardware_buffer_->buffer, sizeof(gamepads)); | |
darin (slow to review)
2011/11/28 17:35:49
i'm not the expert on our dynamic annotations syst
scottmg
2011/11/28 20:02:08
OK, will do.
| |
44 start = base::subtle::Acquire_Load(&gamepad_hardware_buffer_->start_marker); | |
45 if (start == end) | |
46 break; | |
47 ++contention_count; | |
48 base::PlatformThread::YieldCurrentThread(); | |
49 } | |
50 HISTOGRAM_COUNTS("Gamepad.ReadContentionCount", contention_count); | |
51 | |
52 if (contention_count == maximum_contention_count) { | |
53 // We failed to successfully read, presumably because the hardware | |
54 // thread was taking unusually long. Don't copy the data to the output | |
55 // buffer, and simply leave what was there before. | |
56 return; | |
57 } | |
58 | |
59 // New data was read successfully, copy it into the output buffer. | |
60 memcpy(&gamepads, &read_into, sizeof(gamepads)); | |
61 | |
62 // Override the "connected" with false until the user has interacted | |
63 // with the gamepad. This is to prevent fingerprinting on drive-by pages. | |
64 for (unsigned i = 0; i < WebKit::WebGamepads::itemsLengthCap; ++i) { | |
65 WebKit::WebGamepad& pad = gamepads.items[i]; | |
66 // If the device is physically connected, then check if we should | |
67 // keep it disabled. We track if any of the primary 4 buttons have been | |
68 // pressed to determine a reasonable intentional interaction from the user. | |
69 if (pad.connected) { | |
70 if (ever_interacted_with_[i]) | |
71 continue; | |
72 const unsigned primaryInteractionButtons = 4; | |
darin (slow to review)
2011/11/28 17:35:49
nit: use kFooBar for google c++ style constants.
scottmg
2011/11/28 20:02:08
Done.
| |
73 for (unsigned j = 0; j < primaryInteractionButtons; ++j) | |
74 ever_interacted_with_[i] |= pad.buttons[j] > 0.5f; | |
75 // If we've not previously set, and the user still hasn't touched | |
76 // these buttons, then don't pass the data on to the Chromium port. | |
77 if (!ever_interacted_with_[i]) | |
78 pad.connected = false; | |
79 } | |
80 } | |
81 } | |
82 | |
83 GamepadUtil::~GamepadUtil() { | |
84 RenderThread::Get()->Send(new GamepadHostMsg_StopPolling()); | |
darin (slow to review)
2011/11/28 17:35:49
note: i'm not sure if you are doing this yet, but
scottmg
2011/11/28 20:02:08
After talking to John I have some other work to do
| |
85 } | |
OLD | NEW |