summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface/Android
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/Android')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Android/Android.cpp65
1 files changed, 50 insertions, 15 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp
index a0a3f7c8c2..0b0609f010 100644
--- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp
@@ -31,6 +31,8 @@
namespace
{
+std::string SOURCE = "Android";
+
jclass s_list_class;
jmethodID s_list_get;
jmethodID s_list_size;
@@ -468,13 +470,13 @@ namespace ciface::Android
class InputBackend final : public ciface::InputBackend
{
public:
- InputBackend(ControllerInterface* controller_interface);
+ explicit InputBackend(ControllerInterface* controller_interface);
~InputBackend();
void PopulateDevices() override;
-private:
- void AddDevice(JNIEnv* env, int device_id);
- void AddSensorDevice(JNIEnv* env);
+ static void AddDevice(JNIEnv* env, int device_id);
+ static void AddSensorDevice(JNIEnv* env);
+ static void RemoveDevice(int device_id);
};
std::unique_ptr<ciface::InputBackend> CreateInputBackend(ControllerInterface* controller_interface)
@@ -611,10 +613,11 @@ private:
class AndroidDevice final : public Core::Device
{
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_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 =
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
AndroidDevice(JNIEnv* env, std::string name)
: 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);
}
@@ -644,7 +647,7 @@ public:
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
{
@@ -666,6 +669,8 @@ public:
return -3;
}
+ std::optional<jint> GetDeviceID() const { return m_device_id; }
+
jobject GetSensorEventListener() { return m_sensor_event_listener; }
private:
@@ -801,6 +806,7 @@ private:
const jobject m_sensor_event_listener;
const int m_source;
const int m_controller_number;
+ const std::optional<jint> m_device_id;
std::string m_name;
};
@@ -944,8 +950,12 @@ InputBackend::~InputBackend()
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 =
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;
}
- auto device = std::make_shared<AndroidDevice>(env, input_device);
+ auto device = std::make_shared<AndroidDevice>(env, device_id, input_device);
env->DeleteLocalRef(input_device);
if (device->Inputs().empty() && device->Outputs().empty())
return;
- GetControllerInterface().AddDevice(device);
+ g_controller_interface.AddDevice(device);
Core::DeviceQualifier qualifier;
qualifier.FromDevice(device.get());
@@ -987,7 +997,7 @@ void InputBackend::AddSensorDevice(JNIEnv* env)
if (device->Inputs().empty() && device->Outputs().empty())
return;
- GetControllerInterface().AddDevice(device);
+ g_controller_interface.AddDevice(device);
Core::DeviceQualifier qualifier;
qualifier.FromDevice(device.get());
@@ -1000,6 +1010,16 @@ void InputBackend::AddSensorDevice(JNIEnv* env)
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()
{
INFO_LOG_FMT(CONTROLLERINTERFACE, "Android populating devices");
@@ -1163,10 +1183,25 @@ Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_notifySe
}
JNIEXPORT void JNICALL
-Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_refreshDevices(JNIEnv* env,
- jclass)
+Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_00024InputDeviceListener_onInputDeviceAdded(
+ JNIEnv* env, jobject, jint device_id)
+{
+ 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)
{
- g_controller_interface.RefreshDevices();
+ // AddDevice will automatically remove the existing device
+ ciface::Android::InputBackend::AddDevice(env, device_id);
}
JNIEXPORT jobjectArray JNICALL