diff --git a/src/Joystick/JoystickManager.cc b/src/Joystick/JoystickManager.cc index ae16d0a895cd5b3330b59f2ca87181b93a1823cf..96c83e303125b6018ec5a94a37ad4b39cc3d07e7 100644 --- a/src/Joystick/JoystickManager.cc +++ b/src/Joystick/JoystickManager.cc @@ -83,6 +83,56 @@ void JoystickManager::setToolbox(QGCToolbox *toolbox) qCDebug(JoystickManagerLog) << "\tSkipping duplicate" << name; } } +#elif defined(__android__) + QMutexLocker lock(&m_mutex); + + computePossibleButtons(); //this is just needed to get number of supported buttons + + QAndroidJniEnvironment env; + QAndroidJniObject o = QAndroidJniObject::callStaticObjectMethod("android/view/InputDevice", "getDeviceIds"); + jintArray jarr = o.object(); + size_t sz = env->GetArrayLength(jarr); + jint *buff = env->GetIntArrayElements(jarr, nullptr); + + int SOURCE_GAMEPAD = QAndroidJniObject::getStaticField("android/view/InputDevice", "SOURCE_GAMEPAD"); + int SOURCE_JOYSTICK = QAndroidJniObject::getStaticField("android/view/InputDevice", "SOURCE_JOYSTICK"); + + for (size_t i = 0; i < sz; ++i) { + int axisCount, buttonCount; + QAndroidJniObject inputDevice = QAndroidJniObject::callStaticObjectMethod("android/view/InputDevice", "getDevice", "(I)Landroid/view/InputDevice;", buff[i]); + int sources = inputDevice.callMethod("getSources", "()I"); + if (((sources & SOURCE_GAMEPAD) != SOURCE_GAMEPAD) //check if the input device is interesting to us + && ((sources & SOURCE_JOYSTICK) != SOURCE_JOYSTICK)) continue; + + //get id and name + QString id = inputDevice.callObjectMethod("getDescriptor", "()Ljava/lang/String;").toString(); + QString name = inputDevice.callObjectMethod("getName", "()Ljava/lang/String;").toString(); + + //get number of buttons + jintArray a = env->NewIntArray(31); + env->SetIntArrayRegion(a,0,31,_possibleButtons); + + //QAndroidJniObject keyMap = inputDevice.callObjectMethod("getKeyCharacterMap", "()Landroid/view/KeyCharacterMap;"); + //QAndroidJniObject btns = keyMap.callStaticObjectMethod("android/view/KeyCharacterMap","deviceHasKeys", "([I)[Z", a); + QAndroidJniObject btns = inputDevice.callObjectMethod("hasKeys", "([I)[Z", a); + jbooleanArray jSupportedButtons = btns.object(); + size_t btn_sz = env->GetArrayLength(jSupportedButtons); + jboolean* supportedButtons = env->GetBooleanArrayElements(jSupportedButtons, nullptr); + buttonCount=0; + for (size_t j=0;jReleaseBooleanArrayElements(jSupportedButtons, supportedButtons, 0); + + //get number of axis + QAndroidJniObject rangeListNative = inputDevice.callObjectMethod("getMotionRanges", "()Ljava/util/List;"); + axisCount = rangeListNative.callMethod("size"); + + qCDebug(JoystickManagerLog) << "\t" << name << "axes:" << axisCount << "buttons:" << buttonCount; + _name2JoystickMap[name] = new Joystick(name, axisCount, buttonCount, buff[i], _multiVehicleManager); + } + + env->ReleaseIntArrayElements(jarr, buff, 0); #endif if (!_name2JoystickMap.count()) { @@ -93,6 +143,37 @@ void JoystickManager::setToolbox(QGCToolbox *toolbox) _setActiveJoystickFromSettings(); } +void JoystickManager::computePossibleButtons() { + static int ret[31]; + int i; + + for (i=1;i<=16;i++) { + QString name = "KEYCODE_BUTTON_"+QString::number(i); + ret[i-1] = QAndroidJniObject::getStaticField("android/view/KeyEvent", name.toStdString().c_str()); + } + i--; + + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_A"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_B"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_C"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_L1"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_L2"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_R1"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_R2"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_MODE"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_SELECT"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_START"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_THUMBL"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_THUMBR"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_X"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_Y"); + ret[i++] = QAndroidJniObject::getStaticField("android/view/KeyEvent", "KEYCODE_BUTTON_Z"); + + for (int j=0;j +#ifdef __android__ + #include + #include + #include + #include + #include +#endif + Q_DECLARE_LOGGING_CATEGORY(JoystickManagerLog) class QGCApplicaiton; @@ -78,6 +86,12 @@ private: static const char * _settingsGroup; static const char * _settingsKeyActiveJoystick; + +#ifdef __android__ + void computePossibleButtons(); + int * _possibleButtons; + QMutex m_mutex; +#endif }; #endif