hack: Temp fix for crash in MOGA lib on Lollipop.
This commit is contained in:
parent
4a917a003e
commit
9e2b28ae46
|
@ -90,7 +90,8 @@ public final class MOGAInput
|
|||
.getDefaultSharedPreferences(act.getApplicationContext());
|
||||
|
||||
mController = Controller.getInstance(act);
|
||||
mController.init();
|
||||
// mController.init();
|
||||
MogaHack.init(mController, this.act);
|
||||
mListener = new ExampleControllerListener();
|
||||
mController.setListener(mListener, new Handler());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* 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 com.reicast.emulator.periph;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
boolean mIsBound = false;
|
||||
java.lang.reflect.Field fIsBound = null;
|
||||
android.content.ServiceConnection mServiceConnection = null;
|
||||
java.lang.reflect.Field fServiceConnection = null;
|
||||
try
|
||||
{
|
||||
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 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
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 == null || resolveInfos.size() != 1 )
|
||||
{
|
||||
Log.e( "MogaHack", "Somebody is trying to intercept our intent. Disabling MOGA controller for security." );
|
||||
return;
|
||||
}
|
||||
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, 1 );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
controller.init();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue