AusweisApp2/src/aidl/AidlBinder.java

151 lines
3.2 KiB
Java
Raw Normal View History

2017-07-03 09:30:10 +02:00
package com.governikus.ausweisapp2;
import android.nfc.Tag;
import android.os.DeadObjectException;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
class AidlBinder extends IAusweisApp2Sdk.Stub
{
public final static String LOG_TAG = AusweisApp2Service.LOG_TAG;
private final AusweisApp2Service mService;
private IAusweisApp2SdkCallback mCallback = null;
private String mCallbackSessionId = null;
public AidlBinder(AusweisApp2Service pService)
{
mService = pService;
}
private void cleanUpDeadCallback()
{
if (mCallback == null)
{
return;
}
IBinder binder = mCallback.asBinder();
if (!binder.isBinderAlive() || !binder.pingBinder())
{
Log.i(LOG_TAG, "Android service: Removing dead callback.");
mCallback = null;
}
}
private void handleRemoteException(RemoteException pException)
{
Log.w(LOG_TAG, "Android service: Connected client send an exception. Dropping client.", pException);
mCallback = null;
}
public synchronized boolean connectSdk(IAusweisApp2SdkCallback pCallback)
{
if (pCallback == null)
{
Log.w(LOG_TAG, "Android service: Supplied callback is null.");
return false;
}
cleanUpDeadCallback();
if (mCallback != null)
{
Log.w(LOG_TAG, "Android service: A client is already connected. Ignoring newly supplied callback.");
return false;
}
mCallback = pCallback;
mCallbackSessionId = resetValidSessionID("");
final boolean secureSessionId = isSecureRandomPsk();
Log.i(LOG_TAG, "Android service: Callback connected.");
try
{
mCallback.sessionIdGenerated(secureSessionId ? mCallbackSessionId : null, secureSessionId);
}
catch (RemoteException e)
{
handleRemoteException(e);
}
return true;
}
private boolean isValidSessionId(String pSessionId)
{
if (mCallback == null || pSessionId.compareTo(mCallbackSessionId) != 0)
{
Log.w(LOG_TAG, "Android service: Invalid sessiond ID!");
return false;
}
return true;
}
public synchronized boolean send(String pSessionId, String pMessageFromClient)
{
Log.d(LOG_TAG, "Android service: Received JSON from client");
if (!isValidSessionId(mCallbackSessionId))
{
return false;
}
aidlSend(pMessageFromClient);
return true;
}
public synchronized boolean updateNfcTag(String pSessionId, Tag pTag)
{
if (!isValidSessionId(mCallbackSessionId))
{
return false;
}
mService.getNfcConnector().updateNfcTag(pTag);
return true;
}
// FIXME This function is meant to return void istead of java.lang.Object but JNI does not like void
public synchronized Object aidlReceive(String pMessageToClient)
{
Log.d(LOG_TAG, "Android service: Passing JSON to client");
if (mCallback == null)
{
Log.d(LOG_TAG, "Android service: Callback not connected.");
return null;
}
try
{
mCallback.receive(pMessageToClient);
}
catch (DeadObjectException e)
{
Log.w(LOG_TAG, "Android service: Connected client is already dead.");
mCallback = null;
}
catch (RemoteException e)
{
handleRemoteException(e);
}
return null;
}
private native String resetValidSessionID(String pPsk);
private native boolean isSecureRandomPsk();
private native void aidlSend(String pMessageFromClient);
}