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 "content/browser/gamepad/gamepad_platform_data_fetcher_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/trace_event/trace_event.h"
15 #include "jni/GamepadList_jni.h"
17 #include "third_party/WebKit/public/platform/WebGamepads.h"
19 using base::android::AttachCurrentThread
;
20 using base::android::CheckException
;
21 using base::android::ClearException
;
22 using base::android::ConvertJavaStringToUTF8
;
23 using base::android::ScopedJavaLocalRef
;
24 using blink::WebGamepad
;
25 using blink::WebGamepads
;
30 GamepadPlatformDataFetcherAndroid::RegisterGamepadPlatformDataFetcherAndroid(
32 return RegisterNativesImpl(env
);
35 GamepadPlatformDataFetcherAndroid::GamepadPlatformDataFetcherAndroid() {
39 GamepadPlatformDataFetcherAndroid::~GamepadPlatformDataFetcherAndroid() {
43 void GamepadPlatformDataFetcherAndroid::GetGamepadData(
44 blink::WebGamepads
* pads
,
45 bool devices_changed_hint
) {
46 TRACE_EVENT0("GAMEPAD", "GetGamepadData");
50 JNIEnv
* env
= AttachCurrentThread();
54 Java_GamepadList_updateGamepadData(env
, reinterpret_cast<intptr_t>(pads
));
57 void GamepadPlatformDataFetcherAndroid::PauseHint(bool paused
) {
58 JNIEnv
* env
= AttachCurrentThread();
62 Java_GamepadList_notifyForGamepadsAccess(env
, paused
);
65 static void SetGamepadData(JNIEnv
* env
,
74 jfloatArray jbuttons
) {
76 blink::WebGamepads
* pads
= reinterpret_cast<WebGamepads
*>(gamepads
);
77 DCHECK_EQ(pads
->length
, unsigned(index
));
78 DCHECK_LT(index
, static_cast<int>(blink::WebGamepads::itemsLengthCap
));
82 blink::WebGamepad
& pad
= pads
->items
[index
];
84 pad
.connected
= connected
;
86 pad
.timestamp
= timestamp
;
88 // Do not set gamepad parameters for all the gamepad devices that are not
93 // Map the Gamepad DeviceName String to the WebGamepad Id. Ideally it should
94 // be mapped to vendor and product information but it is only available at
95 // kernel level and it can not be queried using class
96 // android.hardware.input.InputManager.
97 // TODO(SaurabhK): Store a cached WebGamePad object in
98 // GamepadPlatformDataFetcherAndroid and only update constant WebGamepad
99 // values when a device has changed.
100 base::string16 device_name
;
101 base::android::ConvertJavaStringToUTF16(env
, devicename
, &device_name
);
102 const size_t name_to_copy
=
103 std::min(device_name
.size(), WebGamepad::idLengthCap
- 1);
106 name_to_copy
* sizeof(base::string16::value_type
));
107 pad
.id
[name_to_copy
] = 0;
109 base::string16 mapping_name
= base::UTF8ToUTF16(mapping
? "standard" : "");
110 const size_t mapping_to_copy
=
111 std::min(mapping_name
.size(), WebGamepad::mappingLengthCap
- 1);
114 mapping_to_copy
* sizeof(base::string16::value_type
));
115 pad
.mapping
[mapping_to_copy
] = 0;
117 pad
.timestamp
= timestamp
;
119 std::vector
<float> axes
;
120 base::android::JavaFloatArrayToFloatVector(env
, jaxes
, &axes
);
122 // Set WebGamepad axeslength to total number of axes on the gamepad device.
123 // Only return the first axesLengthCap if axeslength captured by GamepadList
124 // is larger than axesLengthCap.
125 pad
.axesLength
= std::min(static_cast<int>(axes
.size()),
126 static_cast<int>(WebGamepad::axesLengthCap
));
128 // Copy axes state to the WebGamepad axes[].
129 for (unsigned int i
= 0; i
< pad
.axesLength
; i
++) {
130 pad
.axes
[i
] = static_cast<double>(axes
[i
]);
133 std::vector
<float> buttons
;
134 base::android::JavaFloatArrayToFloatVector(env
, jbuttons
, &buttons
);
136 // Set WebGamepad buttonslength to total number of axes on the gamepad
137 // device. Only return the first buttonsLengthCap if axeslength captured by
138 // GamepadList is larger than buttonsLengthCap.
139 pad
.buttonsLength
= std::min(static_cast<int>(buttons
.size()),
140 static_cast<int>(WebGamepad::buttonsLengthCap
));
142 // Copy buttons state to the WebGamepad buttons[].
143 for (unsigned int j
= 0; j
< pad
.buttonsLength
; j
++) {
144 pad
.buttons
[j
].pressed
= buttons
[j
];
145 pad
.buttons
[j
].value
= buttons
[j
];
149 } // namespace content