AndroidGamepad.cpp (4175B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // TODO: Bug 680289, implement gamepad haptics for Android. 8 // TODO: Bug 1523355, implement gamepad lighindicator and touch for 9 // Android. 10 11 #include "mozilla/Tainting.h" 12 #include "mozilla/dom/Gamepad.h" 13 #include "mozilla/dom/GamepadHandle.h" 14 #include "mozilla/dom/GamepadPlatformService.h" 15 #include "mozilla/java/AndroidGamepadManagerNatives.h" 16 #include "mozilla/java/GeckoAppShellWrappers.h" 17 #include "nsThreadUtils.h" 18 19 using mozilla::dom::GamepadHandle; 20 21 namespace mozilla { 22 namespace dom { 23 24 class AndroidGamepadManager final 25 : public java::AndroidGamepadManager::Natives<AndroidGamepadManager> { 26 AndroidGamepadManager() = delete; 27 28 public: 29 static jni::ByteArray::LocalRef NativeAddGamepad(jni::String::Param aName) { 30 RefPtr<GamepadPlatformService> service = 31 GamepadPlatformService::GetParentService(); 32 MOZ_RELEASE_ASSERT(service); 33 34 nsCString name = aName->ToCString(); 35 if (name.IsEmpty()) { 36 name.AssignLiteral("android"); 37 } 38 39 const GamepadHandle gamepadHandle = service->AddGamepad( 40 name.get(), GamepadMappingType::Standard, GamepadHand::_empty, 41 kStandardGamepadButtons, kStandardGamepadAxes, 0, 0, 0); 42 43 return mozilla::jni::ByteArray::New( 44 reinterpret_cast<const int8_t*>(&gamepadHandle), sizeof(gamepadHandle)); 45 } 46 47 static void NativeRemoveGamepad(jni::ByteArray::Param aGamepadHandleBytes) { 48 GamepadHandle handle = JNIByteArrayToGamepadHandle(aGamepadHandleBytes); 49 50 RefPtr<GamepadPlatformService> service = 51 GamepadPlatformService::GetParentService(); 52 if (!service) { 53 return; 54 } 55 56 service->RemoveGamepad(handle); 57 } 58 59 static void OnButtonChange(jni::ByteArray::Param aGamepadHandleBytes, 60 int32_t aButton, bool aPressed, float aValue) { 61 GamepadHandle handle = JNIByteArrayToGamepadHandle(aGamepadHandleBytes); 62 63 RefPtr<GamepadPlatformService> service = 64 GamepadPlatformService::GetParentService(); 65 if (!service) { 66 return; 67 } 68 69 service->NewButtonEvent(handle, aButton, aPressed, aValue); 70 } 71 72 static void OnAxisChange(jni::ByteArray::Param aGamepadHandleBytes, 73 jni::BooleanArray::Param aValid, 74 jni::FloatArray::Param aValues) { 75 GamepadHandle handle = JNIByteArrayToGamepadHandle(aGamepadHandleBytes); 76 77 RefPtr<GamepadPlatformService> service = 78 GamepadPlatformService::GetParentService(); 79 if (!service) { 80 return; 81 } 82 83 const auto& valid = aValid->GetElements(); 84 const auto& values = aValues->GetElements(); 85 MOZ_ASSERT(valid.Length() == values.Length()); 86 87 for (size_t i = 0; i < values.Length(); i++) { 88 if (valid[i]) { 89 service->NewAxisMoveEvent(handle, i, values[i]); 90 } 91 } 92 } 93 94 private: 95 static GamepadHandle JNIByteArrayToGamepadHandle( 96 jni::ByteArray::Param aGamepadHandleBytes) { 97 MOZ_ASSERT(aGamepadHandleBytes->Length() == sizeof(GamepadHandle)); 98 99 GamepadHandle gamepadHandle; 100 aGamepadHandleBytes->CopyTo(reinterpret_cast<int8_t*>(&gamepadHandle), 101 sizeof(gamepadHandle)); 102 103 return gamepadHandle; 104 } 105 }; 106 107 void StartGamepadMonitoring() { 108 AndroidGamepadManager::Init(); 109 java::AndroidGamepadManager::Start( 110 java::GeckoAppShell::GetApplicationContext()); 111 } 112 113 void StopGamepadMonitoring() { 114 java::AndroidGamepadManager::Stop( 115 java::GeckoAppShell::GetApplicationContext()); 116 } 117 118 void SetGamepadLightIndicatorColor(const Tainted<GamepadHandle>& aGamepadHandle, 119 const Tainted<uint32_t>& aLightColorIndex, 120 const uint8_t& aRed, const uint8_t& aGreen, 121 const uint8_t& aBlue) { 122 NS_WARNING("Android doesn't support gamepad light indicator."); 123 } 124 125 } // namespace dom 126 } // namespace mozilla