Merge pull request #14329 from JosJuice/android-hotplug
Android: Rework input device hotplug
This commit is contained in:
+3
-11
@@ -95,11 +95,6 @@ object ControllerInterface {
|
|||||||
deviceQualifier: String, axisNames: Array<String>, suspended: Boolean
|
deviceQualifier: String, axisNames: Array<String>, suspended: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
|
||||||
* Rescans for input devices.
|
|
||||||
*/
|
|
||||||
external fun refreshDevices()
|
|
||||||
|
|
||||||
external fun getAllDeviceStrings(): Array<String>
|
external fun getAllDeviceStrings(): Array<String>
|
||||||
|
|
||||||
external fun getDevice(deviceString: String): CoreDevice?
|
external fun getDevice(deviceString: String): CoreDevice?
|
||||||
@@ -193,13 +188,10 @@ object ControllerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class InputDeviceListener : InputManager.InputDeviceListener {
|
private class InputDeviceListener : InputManager.InputDeviceListener {
|
||||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
override external fun onInputDeviceAdded(deviceId: Int)
|
||||||
override fun onInputDeviceAdded(deviceId: Int) = refreshDevices()
|
|
||||||
|
|
||||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
override external fun onInputDeviceRemoved(deviceId: Int)
|
||||||
override fun onInputDeviceRemoved(deviceId: Int) = refreshDevices()
|
|
||||||
|
|
||||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
override external fun onInputDeviceChanged(deviceId: Int)
|
||||||
override fun onInputDeviceChanged(deviceId: Int) = refreshDevices()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
std::string SOURCE = "Android";
|
||||||
|
|
||||||
jclass s_list_class;
|
jclass s_list_class;
|
||||||
jmethodID s_list_get;
|
jmethodID s_list_get;
|
||||||
jmethodID s_list_size;
|
jmethodID s_list_size;
|
||||||
@@ -468,13 +470,13 @@ namespace ciface::Android
|
|||||||
class InputBackend final : public ciface::InputBackend
|
class InputBackend final : public ciface::InputBackend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InputBackend(ControllerInterface* controller_interface);
|
explicit InputBackend(ControllerInterface* controller_interface);
|
||||||
~InputBackend();
|
~InputBackend();
|
||||||
void PopulateDevices() override;
|
void PopulateDevices() override;
|
||||||
|
|
||||||
private:
|
static void AddDevice(JNIEnv* env, int device_id);
|
||||||
void AddDevice(JNIEnv* env, int device_id);
|
static void AddSensorDevice(JNIEnv* env);
|
||||||
void AddSensorDevice(JNIEnv* env);
|
static void RemoveDevice(int device_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<ciface::InputBackend> CreateInputBackend(ControllerInterface* controller_interface)
|
std::unique_ptr<ciface::InputBackend> CreateInputBackend(ControllerInterface* controller_interface)
|
||||||
@@ -611,10 +613,11 @@ private:
|
|||||||
class AndroidDevice final : public Core::Device
|
class AndroidDevice final : public Core::Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AndroidDevice(JNIEnv* env, jobject input_device)
|
AndroidDevice(JNIEnv* env, jint device_id, jobject input_device)
|
||||||
: m_sensor_event_listener(AddSensors(env, input_device)),
|
: m_sensor_event_listener(AddSensors(env, input_device)),
|
||||||
m_source(env->CallIntMethod(input_device, s_input_device_get_sources)),
|
m_source(env->CallIntMethod(input_device, s_input_device_get_sources)),
|
||||||
m_controller_number(env->CallIntMethod(input_device, s_input_device_get_controller_number))
|
m_controller_number(env->CallIntMethod(input_device, s_input_device_get_controller_number)),
|
||||||
|
m_device_id(device_id)
|
||||||
{
|
{
|
||||||
jstring j_name =
|
jstring j_name =
|
||||||
reinterpret_cast<jstring>(env->CallObjectMethod(input_device, s_input_device_get_name));
|
reinterpret_cast<jstring>(env->CallObjectMethod(input_device, s_input_device_get_name));
|
||||||
@@ -631,7 +634,7 @@ public:
|
|||||||
// Constructor for the device added by Dolphin to contain sensor inputs
|
// Constructor for the device added by Dolphin to contain sensor inputs
|
||||||
AndroidDevice(JNIEnv* env, std::string name)
|
AndroidDevice(JNIEnv* env, std::string name)
|
||||||
: m_sensor_event_listener(AddSensors(env, nullptr)), m_source(AINPUT_SOURCE_SENSOR),
|
: m_sensor_event_listener(AddSensors(env, nullptr)), m_source(AINPUT_SOURCE_SENSOR),
|
||||||
m_controller_number(0), m_name(std::move(name))
|
m_controller_number(0), m_device_id(std::nullopt), m_name(std::move(name))
|
||||||
{
|
{
|
||||||
AddSystemMotors(env);
|
AddSystemMotors(env);
|
||||||
}
|
}
|
||||||
@@ -644,7 +647,7 @@ public:
|
|||||||
|
|
||||||
std::string GetName() const override { return m_name; }
|
std::string GetName() const override { return m_name; }
|
||||||
|
|
||||||
std::string GetSource() const override { return "Android"; }
|
std::string GetSource() const override { return SOURCE; }
|
||||||
|
|
||||||
std::optional<int> GetPreferredId() const override
|
std::optional<int> GetPreferredId() const override
|
||||||
{
|
{
|
||||||
@@ -666,6 +669,8 @@ public:
|
|||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<jint> GetDeviceID() const { return m_device_id; }
|
||||||
|
|
||||||
jobject GetSensorEventListener() { return m_sensor_event_listener; }
|
jobject GetSensorEventListener() { return m_sensor_event_listener; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -801,6 +806,7 @@ private:
|
|||||||
const jobject m_sensor_event_listener;
|
const jobject m_sensor_event_listener;
|
||||||
const int m_source;
|
const int m_source;
|
||||||
const int m_controller_number;
|
const int m_controller_number;
|
||||||
|
const std::optional<jint> m_device_id;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -944,8 +950,12 @@ InputBackend::~InputBackend()
|
|||||||
env->DeleteGlobalRef(s_keycodes_array);
|
env->DeleteGlobalRef(s_keycodes_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputBackend::AddDevice(JNIEnv* env, int device_id)
|
void InputBackend::AddDevice(JNIEnv* env, jint device_id)
|
||||||
{
|
{
|
||||||
|
// Remove the device in case it already exists (maybe it's possible for a device to connect,
|
||||||
|
// be processed by PopulateDevices, and then be processed by onInputDeviceAdded)
|
||||||
|
RemoveDevice(device_id);
|
||||||
|
|
||||||
jobject input_device =
|
jobject input_device =
|
||||||
env->CallStaticObjectMethod(s_input_device_class, s_input_device_get_device, device_id);
|
env->CallStaticObjectMethod(s_input_device_class, s_input_device_get_device, device_id);
|
||||||
|
|
||||||
@@ -955,14 +965,14 @@ void InputBackend::AddDevice(JNIEnv* env, int device_id)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto device = std::make_shared<AndroidDevice>(env, input_device);
|
auto device = std::make_shared<AndroidDevice>(env, device_id, input_device);
|
||||||
|
|
||||||
env->DeleteLocalRef(input_device);
|
env->DeleteLocalRef(input_device);
|
||||||
|
|
||||||
if (device->Inputs().empty() && device->Outputs().empty())
|
if (device->Inputs().empty() && device->Outputs().empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GetControllerInterface().AddDevice(device);
|
g_controller_interface.AddDevice(device);
|
||||||
|
|
||||||
Core::DeviceQualifier qualifier;
|
Core::DeviceQualifier qualifier;
|
||||||
qualifier.FromDevice(device.get());
|
qualifier.FromDevice(device.get());
|
||||||
@@ -987,7 +997,7 @@ void InputBackend::AddSensorDevice(JNIEnv* env)
|
|||||||
if (device->Inputs().empty() && device->Outputs().empty())
|
if (device->Inputs().empty() && device->Outputs().empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GetControllerInterface().AddDevice(device);
|
g_controller_interface.AddDevice(device);
|
||||||
|
|
||||||
Core::DeviceQualifier qualifier;
|
Core::DeviceQualifier qualifier;
|
||||||
qualifier.FromDevice(device.get());
|
qualifier.FromDevice(device.get());
|
||||||
@@ -1000,6 +1010,16 @@ void InputBackend::AddSensorDevice(JNIEnv* env)
|
|||||||
env->DeleteLocalRef(j_qualifier);
|
env->DeleteLocalRef(j_qualifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputBackend::RemoveDevice(jint device_id)
|
||||||
|
{
|
||||||
|
g_controller_interface.RemoveDevice([device_id](const ciface::Core::Device* device) {
|
||||||
|
return device->GetSource() == SOURCE &&
|
||||||
|
static_cast<const AndroidDevice*>(device)->GetDeviceID() == device_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
s_device_id_to_device_qualifier.erase(device_id);
|
||||||
|
}
|
||||||
|
|
||||||
void InputBackend::PopulateDevices()
|
void InputBackend::PopulateDevices()
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(CONTROLLERINTERFACE, "Android populating devices");
|
INFO_LOG_FMT(CONTROLLERINTERFACE, "Android populating devices");
|
||||||
@@ -1163,10 +1183,25 @@ Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_notifySe
|
|||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_refreshDevices(JNIEnv* env,
|
Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_00024InputDeviceListener_onInputDeviceAdded(
|
||||||
jclass)
|
JNIEnv* env, jobject, jint device_id)
|
||||||
{
|
{
|
||||||
g_controller_interface.RefreshDevices();
|
ciface::Android::InputBackend::AddDevice(env, device_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_00024InputDeviceListener_onInputDeviceRemoved(
|
||||||
|
JNIEnv*, jobject, jint device_id)
|
||||||
|
{
|
||||||
|
ciface::Android::InputBackend::RemoveDevice(device_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_00024InputDeviceListener_onInputDeviceChanged(
|
||||||
|
JNIEnv* env, jobject, jint device_id)
|
||||||
|
{
|
||||||
|
// AddDevice will automatically remove the existing device
|
||||||
|
ciface::Android::InputBackend::AddDevice(env, device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jobjectArray JNICALL
|
JNIEXPORT jobjectArray JNICALL
|
||||||
|
|||||||
Reference in New Issue
Block a user