diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt index d5945f2784..e09e0dec99 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt @@ -30,10 +30,14 @@ object ControllerInterface { private var inputStateUpdatePending = AtomicBoolean(false) private val inputStateVersion = MutableLiveData(0) + private val devicesVersion = MutableLiveData(0) val inputStateChanged: LiveData get() = inputStateVersion + val devicesChanged: LiveData + get() = devicesVersion + /** * Activities which want to pass on inputs to native code * should call this in their own dispatchKeyEvent method. @@ -117,6 +121,14 @@ object ControllerInterface { } } + @Keep + @JvmStatic + private fun onDevicesChanged() { + Handler(Looper.getMainLooper()).post { + devicesVersion.value = devicesVersion.value?.plus(1) + } + } + @Keep @JvmStatic private fun registerInputDeviceListener() { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingDialog.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingDialog.kt index 2117ed3102..803f6e4cc6 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingDialog.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingDialog.kt @@ -25,7 +25,7 @@ class AdvancedMappingDialog( private val controlReference: ControlReference, private val controller: EmulatedController ) : AlertDialog(context), OnItemClickListener { - private val devices: Array = ControllerInterface.getAllDeviceStrings() + private lateinit var devices: Array private val controlAdapter: AdvancedMappingControlAdapter private lateinit var selectedDevice: String @@ -36,10 +36,6 @@ class AdvancedMappingDialog( binding.dropdownDevice.onItemClickListener = this - val deviceAdapter = - ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, devices) - binding.dropdownDevice.setAdapter(deviceAdapter) - controlAdapter = AdvancedMappingControlAdapter(lifecycle, controlReference.isInput()) { control: String -> onControlClicked(control) } @@ -52,6 +48,12 @@ class AdvancedMappingDialog( binding.editExpression.setText(controlReference.getExpression()) + ControllerInterface.devicesChanged.observe(this) { + onDevicesChanged() + setSelectedDevice(selectedDevice) + } + + onDevicesChanged() selectDefaultDevice() } @@ -72,6 +74,13 @@ class AdvancedMappingDialog( return super.dispatchGenericMotionEvent(event) } + private fun onDevicesChanged() { + devices = ControllerInterface.getAllDeviceStrings() + binding.dropdownDevice.setAdapter( + ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, devices) + ) + } + private fun setSelectedDevice(deviceString: String) { selectedDevice = deviceString diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp index 72d7239f9a..476aaa5537 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp @@ -442,6 +442,25 @@ std::shared_ptr FindDevice(jint device_id) return device; } +void RegisterDevicesChangedCallbackIfNeeded(JNIEnv* env, jclass controller_interface_class) +{ + static bool registered = false; + if (registered) + return; + registered = true; + + const jclass global_controller_interface_class = + reinterpret_cast(env->NewGlobalRef(controller_interface_class)); + const jmethodID controller_interface_on_devices_changed = + env->GetStaticMethodID(global_controller_interface_class, "onDevicesChanged", "()V"); + + g_controller_interface.RegisterDevicesChangedCallback( + [global_controller_interface_class, controller_interface_on_devices_changed] { + IDCache::GetEnvForThread()->CallStaticVoidMethod(global_controller_interface_class, + controller_interface_on_devices_changed); + }); +} + } // namespace namespace ciface::Android @@ -903,6 +922,8 @@ InputBackend::InputBackend(ControllerInterface* controller_interface) env->CallStaticVoidMethod(s_controller_interface_class, s_controller_interface_register_input_device_listener); + + RegisterDevicesChangedCallbackIfNeeded(env, s_controller_interface_class); } InputBackend::~InputBackend()