diff options
| author | JosJuice <josjuice@gmail.com> | 2022-03-06 20:27:25 +0100 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2023-03-03 22:28:23 +0100 |
| commit | 104ea098921846e01eb58ebfa00822b14da46cda (patch) | |
| tree | 11f82b21f94f17731fefcfce6ac27ac4bfbf0d7f /Source/Android | |
| parent | d6af294a2370b1827508cdf1819ad7cedbb39f7b (diff) | |
ControllerInterface/Android: Implement hotplug
Diffstat (limited to 'Source/Android')
2 files changed, 130 insertions, 0 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.java index 80d21eeb57..8a7bc8177f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.java @@ -2,15 +2,50 @@ package org.dolphinemu.dolphinemu.features.input.model; +import android.content.Context; +import android.hardware.input.InputManager; +import android.os.Handler; import android.view.KeyEvent; import android.view.MotionEvent; +import androidx.annotation.Keep; + +import org.dolphinemu.dolphinemu.DolphinApplication; +import org.dolphinemu.dolphinemu.utils.LooperThread; + /** * This class interfaces with the native ControllerInterface, * which is where the emulator core gets inputs from. */ public final class ControllerInterface { + private static final class InputDeviceListener implements InputManager.InputDeviceListener + { + @Override + public void onInputDeviceAdded(int deviceId) + { + // Simple implementation for now. We could do something fancier if we wanted to. + refreshDevices(); + } + + @Override + public void onInputDeviceRemoved(int deviceId) + { + // Simple implementation for now. We could do something fancier if we wanted to. + refreshDevices(); + } + + @Override + public void onInputDeviceChanged(int deviceId) + { + // Simple implementation for now. We could do something fancier if we wanted to. + refreshDevices(); + } + } + + private static InputDeviceListener mInputDeviceListener; + private static LooperThread mLooperThread; + /** * Activities which want to pass on inputs to native code * should call this in their own dispatchKeyEvent method. @@ -28,4 +63,41 @@ public final class ControllerInterface * false if the event should be passed on to the default dispatchGenericMotionEvent. */ public static native boolean dispatchGenericMotionEvent(MotionEvent event); + + /** + * Rescans for input devices. + */ + public static native void refreshDevices(); + + @Keep + private static void registerInputDeviceListener() + { + if (mLooperThread == null) + { + mLooperThread = new LooperThread("Hotplug thread"); + mLooperThread.start(); + } + + if (mInputDeviceListener == null) + { + InputManager im = (InputManager) + DolphinApplication.getAppContext().getSystemService(Context.INPUT_SERVICE); + + mInputDeviceListener = new InputDeviceListener(); + im.registerInputDeviceListener(mInputDeviceListener, new Handler(mLooperThread.getLooper())); + } + } + + @Keep + private static void unregisterInputDeviceListener() + { + if (mInputDeviceListener != null) + { + InputManager im = (InputManager) + DolphinApplication.getAppContext().getSystemService(Context.INPUT_SERVICE); + + im.unregisterInputDeviceListener(mInputDeviceListener); + mInputDeviceListener = null; + } + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/LooperThread.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/LooperThread.java new file mode 100644 index 0000000000..8a67ec7e89 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/LooperThread.java @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.utils; + +import android.os.Looper; + +public class LooperThread extends Thread +{ + private Looper mLooper; + + public LooperThread() + { + super(); + } + + public LooperThread(String name) + { + super(name); + } + + @Override + public void run() + { + Looper.prepare(); + + synchronized (this) + { + mLooper = Looper.myLooper(); + notifyAll(); + } + + Looper.loop(); + } + + public Looper getLooper() + { + if (!isAlive()) + { + throw new IllegalStateException(); + } + + synchronized (this) + { + while (mLooper == null) + { + try + { + wait(); + } + catch (InterruptedException ignored) + { + } + } + } + + return mLooper; + } +} |
