Merge pull request #20762 from hrydgard/more-cleanup

Android: Remove support for Moga controllers
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2025-08-29 22:00:40 +02:00
commit ea2e52e02a
12 files changed
+4 -480

No files matched your search

-9
View File
@@ -243,12 +243,3 @@ android {
afterEvaluate {
android.sourceSets.main.assets.getSrcDirs().each { println it }
}
// F-Droid lite version can be created with : ./gradlew assembleOptimized -Pf_droid
if (project.hasProperty("f_droid")) {
project.android.sourceSets.main.java.srcDirs += 'libs/MogaStubs'
} else {
project.dependencies {
implementation files('libs/com.bda.controller.jar')
}
}
@@ -1,39 +0,0 @@
package com.bda.controller;
import android.app.Activity;
import android.os.Handler;
import android.view.SurfaceView;
public class Controller {
public static final int ACTION_VERSION_MOGA = 0;
public static final int STATE_CURRENT_PRODUCT_VERSION = 1;
static Controller sInstance;
private Controller() {}
public static Controller getInstance(Activity activity) {
if (sInstance == null) {
sInstance = new Controller();
}
return sInstance;
}
public int getState(int val) {
return 0;
}
public int setListener(SurfaceView view, Handler handler) {
return 0;
}
public int init() {
return 0;
}
public int onPause() {
return 0;
}
public int onResume() {
return 0;
}
public int exit() {
return 0;
}
}
@@ -1,9 +0,0 @@
package com.bda.controller;
public interface ControllerListener {
public abstract void onKeyEvent(KeyEvent event);
public abstract void onMotionEvent(MotionEvent event);
public abstract void onStateEvent(StateEvent state);
}
@@ -1,4 +0,0 @@
package com.bda.controller;
public class IControllerService {
}
@@ -1,20 +0,0 @@
package com.bda.controller;
public class KeyEvent {
public static final int ACTION_DOWN = 0;
public static final int ACTION_UP = 1;
public static final int KEYCODE_DPAD_UP = 2;
public static final int KEYCODE_DPAD_DOWN = 3;
public static final int KEYCODE_DPAD_LEFT = 4;
public static final int KEYCODE_DPAD_RIGHT = 5;
public int getAction() {
return 0;
}
public int getState(int val) {
return 0;
}
public int getKeyCode() {
return 0;
}
}
@@ -1,14 +0,0 @@
package com.bda.controller;
public class MotionEvent {
public static final int AXIS_X = 0;
public static final int AXIS_Y = 1;
public static final int AXIS_Z = 2;
public static final int AXIS_RZ = 3;
public static final int AXIS_LTRIGGER = 4;
public static final int AXIS_RTRIGGER = 5;
public int getAxisValue(int val) {
return 0;
}
}
@@ -1,19 +0,0 @@
package com.bda.controller;
public class StateEvent {
public static final int STATE_POWER_LOW = 0;
public static final int STATE_CONNECTION = 1;
public static final int ACTION_FALSE = 0;
public static final int ACTION_TRUE = 1;
public static final int ACTION_DISCONNECTED = 2;
public static final int ACTION_CONNECTING = 3;
public static final int ACTION_CONNECTED = 4;
public int getAction() {
return 0;
}
public int getState() {
return 0;
}
}
Binary file not shown.
-101
View File
@@ -1,101 +0,0 @@
/**
* Mupen64PlusAE, an N64 emulator for the Android platform
*
* Copyright (C) 2013 Paul Lamb
*
* This file is part of Mupen64PlusAE.
*
* Mupen64PlusAE is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Mupen64PlusAE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Mupen64PlusAE. If
* not, see <http://www.gnu.org/licenses/>.
*
* Authors: Paul Lamb
*/
package org.ppsspp.ppsspp;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.util.Log;
import com.bda.controller.Controller;
import com.bda.controller.IControllerService;
import java.util.List;
/**
* Temporary hack for crash in MOGA library on Lollipop. This hack can be removed once MOGA fixes
* their library. The actual issue is caused by the use of implicit service intents, which are
* illegal in Lollipop, as seen in the logcat message below.
*
* <pre>
* {@code Service Intent must be explicit: Intent { act=com.bda.controller.IControllerService } }
* </pre>
*
* @see <a href="http://www.mogaanywhere.com/developers/">MOGA developer site</a>
* @see <a href="http://commonsware.com/blog/2014/06/29/dealing-deprecations-bindservice.html">
* Discussion on explicit intents</a>
*/
public class MogaHack {
public static void init(Controller controller, Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
controller.init();
return;
}
try {
boolean mIsBound = false;
java.lang.reflect.Field fIsBound = null;
android.content.ServiceConnection mServiceConnection = null;
java.lang.reflect.Field fServiceConnection = null;
Class<?> cMogaController = controller.getClass();
fIsBound = cMogaController.getDeclaredField("mIsBound");
fIsBound.setAccessible(true);
mIsBound = fIsBound.getBoolean(controller);
fServiceConnection = cMogaController.getDeclaredField("mServiceConnection");
fServiceConnection.setAccessible(true);
mServiceConnection = (android.content.ServiceConnection) fServiceConnection.get(controller);
if ((!mIsBound) && (mServiceConnection != null)) {
// Convert implicit intent to explicit intent, see http://stackoverflow.com/a/26318757
Intent intent = new Intent(IControllerService.class.getName());
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentServices(intent, 0);
if (resolveInfos.size() != 1) {
// What? this doesn't do anything.
// Log.e("MogaHack", "Somebody is trying to intercept our intent. Disabling MOGA controller for security.");
}
ServiceInfo serviceInfo = resolveInfos.get(0).serviceInfo;
String packageName = serviceInfo.packageName;
String className = serviceInfo.name;
intent.setComponent(new ComponentName(packageName, className));
// Start the service explicitly
context.startService(intent);
context.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE );
try {
fIsBound.setBoolean(controller, true);
} catch (IllegalAccessException e) {
Log.e("MogaHack", "MOGA Lollipop Hack IllegalAccessException (set)", e);
} catch (IllegalArgumentException e) {
Log.e("MogaHack", "MOGA Lollipop Hack IllegalArgumentException (set)", e);
}
}
} catch (NoSuchFieldException e) {
Log.e("MogaHack", "MOGA Lollipop Hack NoSuchFieldException (get)", e);
} catch (IllegalAccessException e) {
Log.e("MogaHack", "MOGA Lollipop Hack IllegalAccessException (get)", e);
} catch (IllegalArgumentException e) {
Log.e("MogaHack", "MOGA Lollipop Hack IllegalArgumentException (get)", e);
} catch (Exception e) {
Log.e("MogaHack", "MOGA", e);
}
}
}
@@ -755,15 +755,9 @@ public abstract class NativeActivity extends Activity {
nativeRenderer = null;
}
}
if (mGLSurfaceView != null) {
mGLSurfaceView.onDestroy();
mGLSurfaceView = null;
}
mGLSurfaceView = null;
} else {
if (mSurfaceView != null) {
mSurfaceView.onDestroy();
mSurfaceView = null;
}
mSurfaceView = null;
mSurface = null;
}
+1 -128
View File
@@ -18,20 +18,11 @@ import android.util.Log;
import android.view.InputDevice;
import android.view.MotionEvent;
import com.bda.controller.Controller;
import com.bda.controller.ControllerListener;
import com.bda.controller.KeyEvent;
import com.bda.controller.StateEvent;
public class NativeGLView extends GLSurfaceView implements SensorEventListener, ControllerListener {
public class NativeGLView extends GLSurfaceView implements SensorEventListener {
private final static String TAG = "NativeGLView";
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
// Moga controller
private final Controller mController;
private boolean isMogaPro = false;
NativeActivity mActivity;
public NativeGLView(NativeActivity activity) {
@@ -40,16 +31,6 @@ public class NativeGLView extends GLSurfaceView implements SensorEventListener,
mSensorManager = (SensorManager) activity.getSystemService(Activity.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mController = Controller.getInstance(activity);
try {
MogaHack.init(mController, activity);
Log.i(TAG, "MOGA initialized");
mController.setListener(this, new Handler());
} catch (Exception e) {
// Log.d(TAG, "MOGA failed to initialize");
}
}
private int getToolType(final MotionEvent ev, int pointer) {
@@ -149,119 +130,11 @@ public class NativeGLView extends GLSurfaceView implements SensorEventListener,
public void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
if (mController != null) {
mController.onPause();
}
}
@Override
public void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
if (mController != null) {
mController.onResume();
// According to the docs, the Moga's state can be inconsistent here.
// We should do a one time poll. TODO
}
}
public void onDestroy() {
if (mController != null) {
mController.exit();
}
}
// MOGA Controller - from ControllerListener
@Override
public void onKeyEvent(KeyEvent event) {
// The Moga left stick doubles as a D-pad. This creates mapping conflicts so let's turn it off.
// Unfortunately this breaks menu navigation in PPSSPP currently but meh.
// This is different on Moga Pro though.
if (!isMogaPro) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_DOWN:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
return;
default:
break;
}
}
boolean repeat = false; // Moga has no repeats?
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
NativeApp.keyDown(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode(), repeat);
break;
case KeyEvent.ACTION_UP:
NativeApp.keyUp(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode());
break;
}
}
// MOGA Controller - from ControllerListener
@Override
public void onMotionEvent(com.bda.controller.MotionEvent event) {
int [] axisIds = new int[]{
com.bda.controller.MotionEvent.AXIS_X,
com.bda.controller.MotionEvent.AXIS_Y,
com.bda.controller.MotionEvent.AXIS_Z,
com.bda.controller.MotionEvent.AXIS_RZ,
com.bda.controller.MotionEvent.AXIS_LTRIGGER,
com.bda.controller.MotionEvent.AXIS_RTRIGGER,
};
float [] values = new float[]{
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_X),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_Y),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_Z),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_RZ),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_LTRIGGER),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_RTRIGGER),
};
NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, axisIds, values, 6);
}
// MOGA Controller - from ControllerListener
@Override
public void onStateEvent(StateEvent state) {
switch (state.getState()) {
case StateEvent.STATE_CONNECTION:
switch (state.getAction()) {
case StateEvent.ACTION_CONNECTED:
Log.i(TAG, "Moga Connected");
if (mController.getState(Controller.STATE_CURRENT_PRODUCT_VERSION) == Controller.ACTION_VERSION_MOGA) {
NativeApp.sendMessageFromJava("moga", "Moga");
} else {
Log.i(TAG, "MOGA Pro detected");
isMogaPro = true;
NativeApp.sendMessageFromJava("moga", "MogaPro");
}
break;
case StateEvent.ACTION_CONNECTING:
Log.i(TAG, "Moga Connecting...");
break;
case StateEvent.ACTION_DISCONNECTED:
Log.i(TAG, "Moga Disconnected (or simply Not connected)");
NativeApp.sendMessageFromJava("moga", "");
break;
}
break;
case StateEvent.STATE_POWER_LOW:
switch (state.getAction()) {
case StateEvent.ACTION_TRUE:
Log.i(TAG, "Moga Power Low");
break;
case StateEvent.ACTION_FALSE:
Log.i(TAG, "Moga Power OK");
break;
}
break;
default:
break;
}
}
}
@@ -21,20 +21,11 @@ import android.view.SurfaceView;
import androidx.annotation.RequiresApi;
import com.bda.controller.Controller;
import com.bda.controller.ControllerListener;
import com.bda.controller.KeyEvent;
import com.bda.controller.StateEvent;
public class NativeSurfaceView extends SurfaceView implements SensorEventListener, ControllerListener {
public class NativeSurfaceView extends SurfaceView implements SensorEventListener {
private static final String TAG = "NativeSurfaceView";
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
// Moga controller
private final Controller mController;
private boolean isMogaPro = false;
public NativeSurfaceView(NativeActivity activity) {
super(activity);
@@ -42,16 +33,6 @@ public class NativeSurfaceView extends SurfaceView implements SensorEventListene
mSensorManager = (SensorManager) activity.getSystemService(Activity.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mController = Controller.getInstance(activity);
try {
MogaHack.init(mController, activity);
Log.i(TAG, "MOGA initialized");
mController.setListener(this, new Handler());
} catch (Exception e) {
// Ignore.
}
}
private int getToolType(final MotionEvent ev, int pointer) {
@@ -170,118 +151,9 @@ public class NativeSurfaceView extends SurfaceView implements SensorEventListene
public void onPause() {
mSensorManager.unregisterListener(this);
if (mController != null) {
mController.onPause();
}
}
public void onResume() {
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
if (mController != null) {
mController.onResume();
// According to the docs, the Moga's state can be inconsistent here.
// Should we do a one time poll?
}
}
public void onDestroy() {
if (mController != null) {
mController.exit();
}
}
// MOGA Controller - from ControllerListener
@Override
public void onKeyEvent(KeyEvent event) {
// The Moga left stick doubles as a D-pad. This creates mapping conflicts so let's turn it off.
// Unfortunately this breaks menu navigation in PPSSPP currently but meh.
// This is different on Moga Pro though.
if (!isMogaPro) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_DOWN:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
return;
default:
break;
}
}
boolean repeat = false; // Moga has no repeats?
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
NativeApp.keyDown(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode(), repeat);
break;
case KeyEvent.ACTION_UP:
NativeApp.keyUp(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode());
break;
}
}
// MOGA Controller - from ControllerListener
@Override
public void onMotionEvent(com.bda.controller.MotionEvent event) {
int [] axisIds = new int[]{
com.bda.controller.MotionEvent.AXIS_X,
com.bda.controller.MotionEvent.AXIS_Y,
com.bda.controller.MotionEvent.AXIS_Z,
com.bda.controller.MotionEvent.AXIS_RZ,
com.bda.controller.MotionEvent.AXIS_LTRIGGER,
com.bda.controller.MotionEvent.AXIS_RTRIGGER,
};
float [] values = new float[]{
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_X),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_Y),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_Z),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_RZ),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_LTRIGGER),
event.getAxisValue(com.bda.controller.MotionEvent.AXIS_RTRIGGER),
};
NativeApp.joystickAxis(NativeApp.DEVICE_ID_PAD_0, axisIds, values, 6);
}
// MOGA Controller - from ControllerListener
@Override
public void onStateEvent(StateEvent state) {
switch (state.getState()) {
case StateEvent.STATE_CONNECTION:
switch (state.getAction()) {
case StateEvent.ACTION_CONNECTED:
Log.i(TAG, "Moga Connected");
if (mController.getState(Controller.STATE_CURRENT_PRODUCT_VERSION) == Controller.ACTION_VERSION_MOGA) {
NativeApp.sendMessageFromJava("moga", "Moga");
} else {
Log.i(TAG, "MOGA Pro detected");
isMogaPro = true;
NativeApp.sendMessageFromJava("moga", "MogaPro");
}
break;
case StateEvent.ACTION_CONNECTING:
Log.i(TAG, "Moga Connecting...");
break;
case StateEvent.ACTION_DISCONNECTED:
Log.i(TAG, "Moga Disconnected (or simply Not connected)");
NativeApp.sendMessageFromJava("moga", "");
break;
}
break;
case StateEvent.STATE_POWER_LOW:
switch (state.getAction()) {
case StateEvent.ACTION_TRUE:
Log.i(TAG, "Moga Power Low");
break;
case StateEvent.ACTION_FALSE:
Log.i(TAG, "Moga Power OK");
break;
}
break;
default:
break;
}
}
}