Merge "Remove SAP socket"
diff --git a/src/com/android/bluetooth/sap/SapRilReceiver.java b/src/com/android/bluetooth/sap/SapRilReceiver.java
index d796fb6..028252c 100644
--- a/src/com/android/bluetooth/sap/SapRilReceiver.java
+++ b/src/com/android/bluetooth/sap/SapRilReceiver.java
@@ -22,8 +22,7 @@
import android.os.RemoteException;
import android.util.Log;
-public class SapRilReceiver implements Runnable {
-
+public class SapRilReceiver {
private static final String TAG = "SapRilReceiver";
public static final boolean DEBUG = true;
public static final boolean VERBOSE = true;
@@ -32,12 +31,9 @@
// match with constant in ril.cpp - as in RIL.java
private static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000;
- LocalSocket mSocket = null;
- CodedOutputStreamMicro mRilBtOutStream = null;
- InputStream mRilBtInStream = null;
-
SapCallback mSapCallback;
volatile ISap mSapProxy = null;
+ Object mSapProxyLock = new Object();
final AtomicLong mSapProxyCookie = new AtomicLong(0);
final SapProxyDeathRecipient mSapProxyDeathRecipient;
@@ -81,6 +77,7 @@
public void connectResponse(int token, int sapConnectRsp, int maxMsgSize) {
Log.d(TAG, "connectResponse: token " + token + " sapConnectRsp " + sapConnectRsp
+ " maxMsgSize " + maxMsgSize);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_CONNECT_RESP);
sapMessage.setConnectionStatus(sapConnectRsp);
if (sapConnectRsp == SapMessage.CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED) {
@@ -92,6 +89,7 @@
public void disconnectResponse(int token) {
Log.d(TAG, "disconnectResponse: token " + token);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_DISCONNECT_RESP);
sapMessage.setResultCode(SapMessage.INVALID_VALUE);
removeOngoingReqAndSendMessage(token, sapMessage);
@@ -100,6 +98,7 @@
public void disconnectIndication(int token, int disconnectType) {
Log.d(TAG,
"disconnectIndication: token " + token + " disconnectType " + disconnectType);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_RIL_UNSOL_DISCONNECT_IND);
sapMessage.setDisconnectionType(disconnectType);
sendSapMessage(sapMessage);
@@ -107,6 +106,7 @@
public void apduResponse(int token, int resultCode, ArrayList<Byte> apduRsp) {
Log.d(TAG, "apduResponse: token " + token);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_TRANSFER_APDU_RESP);
sapMessage.setResultCode(resultCode);
if (resultCode == SapMessage.RESULT_OK) {
@@ -117,6 +117,7 @@
public void transferAtrResponse(int token, int resultCode, ArrayList<Byte> atr) {
Log.d(TAG, "transferAtrResponse: token " + token + " resultCode " + resultCode);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_TRANSFER_ATR_RESP);
sapMessage.setResultCode(resultCode);
if (resultCode == SapMessage.RESULT_OK) {
@@ -127,6 +128,7 @@
public void powerResponse(int token, int resultCode) {
Log.d(TAG, "powerResponse: token " + token + " resultCode " + resultCode);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
Integer reqType = SapMessage.sOngoingRequests.remove(token);
if (VERBOSE) {
Log.d(TAG, "powerResponse: reqType "
@@ -146,6 +148,7 @@
public void resetSimResponse(int token, int resultCode) {
Log.d(TAG, "resetSimResponse: token " + token + " resultCode " + resultCode);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_RESET_SIM_RESP);
sapMessage.setResultCode(resultCode);
removeOngoingReqAndSendMessage(token, sapMessage);
@@ -153,6 +156,7 @@
public void statusIndication(int token, int status) {
Log.d(TAG, "statusIndication: token " + token + " status " + status);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_STATUS_IND);
sapMessage.setStatusChange(status);
sendSapMessage(sapMessage);
@@ -162,6 +166,7 @@
int token, int resultCode, int cardReaderStatus) {
Log.d(TAG, "transferCardReaderStatusResponse: token " + token + " resultCode "
+ resultCode + " cardReaderStatus " + cardReaderStatus);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_TRANSFER_CARD_READER_STATUS_RESP);
sapMessage.setResultCode(resultCode);
if (resultCode == SapMessage.RESULT_OK) {
@@ -172,6 +177,7 @@
public void errorResponse(int token) {
Log.d(TAG, "errorResponse: token " + token);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
// Since ERROR_RESP isn't supported by createUnsolicited(), keeping behavior same here
// SapMessage sapMessage = new SapMessage(SapMessage.ID_ERROR_RESP);
SapMessage sapMessage = new SapMessage(SapMessage.ID_RIL_UNKNOWN);
@@ -180,6 +186,7 @@
public void transferProtocolResponse(int token, int resultCode) {
Log.d(TAG, "transferProtocolResponse: token " + token + " resultCode " + resultCode);
+ SapService.notifyUpdateWakeLock(mSapServiceHandler);
SapMessage sapMessage = new SapMessage(SapMessage.ID_SET_TRANSPORT_PROTOCOL_RESP);
sapMessage.setResultCode(resultCode);
removeOngoingReqAndSendMessage(token, sapMessage);
@@ -194,36 +201,46 @@
return ret;
}
+ public Object getSapProxyLock() {
+ return mSapProxyLock;
+ }
+
public ISap getSapProxy() {
- if (mSapProxy != null) {
+ synchronized (mSapProxyLock) {
+ if (mSapProxy != null) {
+ return mSapProxy;
+ }
+
+ try {
+ mSapProxy = ISap.getService(SOCKET_NAME_RIL_BT);
+ if (mSapProxy != null) {
+ mSapProxy.linkToDeath(
+ mSapProxyDeathRecipient, mSapProxyCookie.incrementAndGet());
+ mSapProxy.setCallback(mSapCallback);
+ } else {
+ Log.e(TAG, "getSapProxy: mSapProxy == null");
+ }
+ } catch (RemoteException | RuntimeException e) {
+ mSapProxy = null;
+ Log.e(TAG, "getSapProxy: exception: " + e);
+ }
+
+ if (mSapProxy == null) {
+ // if service is not up, treat it like death notification to try to get service
+ // again
+ mSapServerMsgHandler.sendMessageDelayed(
+ mSapServerMsgHandler.obtainMessage(
+ SapServer.SAP_PROXY_DEAD, mSapProxyCookie.get()),
+ SapServer.ISAP_GET_SERVICE_DELAY_MILLIS);
+ }
return mSapProxy;
}
-
- try {
- mSapProxy = ISap.getService(SOCKET_NAME_RIL_BT);
- if (mSapProxy != null) {
- Log.d(TAG, "getSapProxy: mSapProxy != null; calling setCallback()");
- mSapProxy.linkToDeath(mSapProxyDeathRecipient, mSapProxyCookie.incrementAndGet());
- mSapProxy.setCallback(mSapCallback);
- } else {
- Log.e(TAG, "getSapProxy: mSapProxy == null");
- }
- } catch (RemoteException | RuntimeException e) {
- mSapProxy = null;
-
- // if service is not up, treat it like death notification to try to get service again
- mSapServerMsgHandler.sendMessageDelayed(
- mSapServerMsgHandler.obtainMessage(
- SapServer.SAP_PROXY_DEAD, mSapProxyCookie.get()),
- SapServer.ISAP_GET_SERVICE_DELAY_MILLIS);
-
- Log.e(TAG, "getSapProxy: exception", e);
- }
- return mSapProxy;
}
public void resetSapProxy() {
- mSapProxy = null;
+ synchronized (mSapProxyLock) {
+ mSapProxy = null;
+ }
}
public SapRilReceiver(Handler SapServerMsgHandler, Handler sapServiceHandler) {
@@ -231,106 +248,19 @@
mSapServiceHandler = sapServiceHandler;
mSapCallback = new SapCallback();
mSapProxyDeathRecipient = new SapProxyDeathRecipient();
- mSapProxy = getSapProxy();
- }
-
- /**
- * Open the RIL-BT socket in rild. Will continuously try to open the BT socket until
- * success. (Based on the approach used to open the rild socket in telephony)
- * @return The socket handle
- */
- public static LocalSocket openRilBtSocket() {
- int retryCount = 0;
- LocalSocket rilSocket = null;
-
- for (;;) {
- LocalSocketAddress address;
-
- try {
- rilSocket = new LocalSocket();
- address = new LocalSocketAddress(SOCKET_NAME_RIL_BT,
- LocalSocketAddress.Namespace.RESERVED);
- rilSocket.connect(address);
- break; // Socket opened
- } catch (IOException ex){
- try {
- if (rilSocket != null) {
- rilSocket.close();
- }
- } catch (IOException ex2) {
- //ignore failure to close after failure to connect
- }
-
- // don't print an error message after the the first time
- // or after the 8th time
- if (retryCount == 8) {
- Log.e (TAG,
- "Couldn't find '" + SOCKET_NAME_RIL_BT
- + "' socket after " + retryCount
- + " times, continuing to retry silently");
- } else if (retryCount > 0 && retryCount < 8) {
- Log.i (TAG,
- "Couldn't find '" + SOCKET_NAME_RIL_BT
- + "' socket; retrying after timeout");
- if (VERBOSE) Log.w(TAG, ex);
- }
-
- try {
- Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
- } catch (InterruptedException er) {
- }
-
- retryCount++;
- continue;
- }
+ synchronized (mSapProxyLock) {
+ mSapProxy = getSapProxy();
}
- return rilSocket;
- }
-
-
- public CodedOutputStreamMicro getRilBtOutStream() {
- return mRilBtOutStream;
}
/**
* Notify SapServer that this class is ready for shutdown.
*/
- private void notifyShutdown() {
+ void notifyShutdown() {
if (DEBUG) Log.i(TAG, "notifyShutdown()");
// If we are already shutdown, don't bother sending a notification.
- synchronized (this) {
- if (mSocket != null) sendShutdownMessage();
- }
- }
-
- /**
- * This will terminate the SapRilReceiver thread, by closing the RIL-BT in-/output
- * streams.
- */
- public void shutdown() {
- if (DEBUG) Log.i(TAG, "shutdown()");
-
- /* On Android you need to close the IOstreams using Socket.shutdown*
- * The IOstream close must not be used, as it some how decouples the
- * stream from the socket, and when the socket is closed, the pending
- * reads never return nor throw and exception.
- * Hence here we use the shutdown method: */
- synchronized (this) {
- if (mSocket != null) {
- try {
- mSocket.shutdownOutput();
- } catch (IOException e) {}
- try {
- mSocket.shutdownInput();
- } catch (IOException e) {}
- try {
- mSocket.close();
- } catch (IOException ex) {
- if (VERBOSE) Log.e(TAG,"Uncaught exception", ex);
- } finally {
- mSocket = null;
- }
- }
+ synchronized (mSapProxyLock) {
+ if (mSapProxy != null) sendShutdownMessage();
}
}
@@ -387,69 +317,9 @@
}
/**
- * The RIL reader thread. Will handle open of the RIL-BT socket, and notify
- * SapServer when done.
- */
- @Override
- public void run() {
-
- try {
- if (VERBOSE) Log.i(TAG, "Starting RilBtReceiverThread...");
-
- mSocket = openRilBtSocket();
- mRilBtInStream = mSocket.getInputStream();
- mRilBtOutStream = CodedOutputStreamMicro.newInstance(mSocket.getOutputStream());
-
- // Notify the SapServer that we have connected to the RilBtSocket
- sendRilConnectMessage();
-
- // The main loop - read messages and forward to SAP server
- for (;;) {
- SapMessage sapMsg = null;
- MsgHeader rilMsg;
-
- if (VERBOSE) Log.i(TAG, "Waiting for incoming message...");
- int length = readMessage(mRilBtInStream, buffer);
-
- SapService.notifyUpdateWakeLock(mSapServiceHandler);
-
- if (length == -1) {
- if (DEBUG) Log.i(TAG, "EOF reached - closing down.");
- break;
- }
-
- CodedInputStreamMicro msgStream =
- CodedInputStreamMicro.newInstance(buffer, 0, length);
-
- rilMsg = MsgHeader.parseFrom(msgStream);
-
- if (VERBOSE) Log.i(TAG, "Message received.");
-
- sapMsg = SapMessage.newInstance(rilMsg);
-
- if (sapMsg != null && sapMsg.getMsgType() != SapMessage.INVALID_VALUE)
- {
- if (sapMsg.getMsgType() < SapMessage.ID_RIL_BASE) {
- sendClientMessage(sapMsg);
- } else {
- sendRilIndMessage(sapMsg);
- }
- } // else simply ignore it
- }
-
- } catch (IOException e) {
- notifyShutdown(); /* Only needed in case of a connection error */
- Log.i(TAG, "'" + SOCKET_NAME_RIL_BT + "' socket inputStream closed", e);
-
- } finally {
- Log.i(TAG, "Disconnected from '" + SOCKET_NAME_RIL_BT + "' socket");
- }
- }
-
- /**
* Notify SapServer that the RIL socket is connected
*/
- private void sendRilConnectMessage() {
+ void sendRilConnectMessage() {
if (mSapServerMsgHandler != null) {
mSapServerMsgHandler.sendEmptyMessage(SapServer.SAP_MSG_RIL_CONNECT);
}
diff --git a/src/com/android/bluetooth/sap/SapServer.java b/src/com/android/bluetooth/sap/SapServer.java
index 527833f..5030970 100644
--- a/src/com/android/bluetooth/sap/SapServer.java
+++ b/src/com/android/bluetooth/sap/SapServer.java
@@ -61,7 +61,6 @@
private BufferedInputStream mRfcommIn = null;
/* References to the SapRilReceiver object */
private SapRilReceiver mRilBtReceiver = null;
- private Thread mRilBtReceiverThread = null;
/* The message handler members */
private Handler mSapHandler = null;
private HandlerThread mHandlerThread = null;
@@ -309,7 +308,6 @@
mSapHandler = new Handler(sapLooper, this);
mRilBtReceiver = new SapRilReceiver(mSapHandler, mSapServiceHandler);
- mRilBtReceiverThread = new Thread(mRilBtReceiver, "RilBtReceiver");
boolean done = false;
while (!done) {
if(VERBOSE) Log.i(TAG, "Waiting for incomming RFCOMM message...");
@@ -452,14 +450,10 @@
mHandlerThread.join();
mHandlerThread = null;
} catch (InterruptedException e) {}
- if(mRilBtReceiverThread != null) try {
- if(mRilBtReceiver != null) {
- mRilBtReceiver.shutdown();
- mRilBtReceiver = null;
- }
- mRilBtReceiverThread.join();
- mRilBtReceiverThread = null;
- } catch (InterruptedException e) {}
+ if (mRilBtReceiver != null) {
+ mRilBtReceiver.resetSapProxy();
+ mRilBtReceiver = null;
+ }
if(mRfcommIn != null) try {
if(VERBOSE) Log.i(TAG, "Closing mRfcommIn...");
@@ -521,9 +515,9 @@
* 2) Send a RIL_SIM_SAP_CONNECT request to RILD
* 3) Send a RIL_SIM_RESET request and a connect confirm to the SAP client */
changeState(SAP_STATE.CONNECTING);
- if(mRilBtReceiverThread != null) {
- // Open the RIL socket, and wait for the complete message: SAP_MSG_RIL_CONNECT
- mRilBtReceiverThread.start();
+ if (mRilBtReceiver != null) {
+ // Notify the SapServer that we have connected to the SAP service
+ mRilBtReceiver.sendRilConnectMessage();
// Don't send reply yet
reply = null;
} else {
@@ -640,6 +634,7 @@
break;
case SAP_PROXY_DEAD:
if ((long) msg.obj == mRilBtReceiver.mSapProxyCookie.get()) {
+ mRilBtReceiver.notifyShutdown(); /* Only needed in case of a connection error */
mRilBtReceiver.resetSapProxy();
// todo: rild should be back up since message was sent with a delay. this is a hack.
@@ -856,25 +851,29 @@
+ SapMessage.getMsgTypeName(sapMsg.getMsgType()));
Log.d(TAG_HANDLER, "sendRilMessage: calling getSapProxy");
- ISap sapProxy = mRilBtReceiver.getSapProxy();
- if (sapProxy == null) {
- Log.e(TAG_HANDLER, "sendRilMessage: Unable to send message to RIL; sapProxy is null");
- sendClientMessage(new SapMessage(SapMessage.ID_ERROR_RESP));
- return;
- }
-
- try {
- sapMsg.send(sapProxy);
- if (VERBOSE) {
- Log.d(TAG_HANDLER, "sendRilMessage: sapMsg.callISapReq called successfully");
+ synchronized (mRilBtReceiver.getSapProxyLock()) {
+ ISap sapProxy = mRilBtReceiver.getSapProxy();
+ if (sapProxy == null) {
+ Log.e(TAG_HANDLER,
+ "sendRilMessage: Unable to send message to RIL; sapProxy is null");
+ sendClientMessage(new SapMessage(SapMessage.ID_ERROR_RESP));
+ return;
}
- } catch (IllegalArgumentException e) {
- Log.e(TAG_HANDLER, "sendRilMessage: IllegalArgumentException", e);
- sendClientMessage(new SapMessage(SapMessage.ID_ERROR_RESP));
- } catch (RemoteException | RuntimeException e) {
- Log.e(TAG_HANDLER, "sendRilMessage: Unable to send message to RIL", e);
- sendClientMessage(new SapMessage(SapMessage.ID_ERROR_RESP));
- mRilBtReceiver.resetSapProxy();
+
+ try {
+ sapMsg.send(sapProxy);
+ if (VERBOSE) {
+ Log.d(TAG_HANDLER, "sendRilMessage: sapMsg.callISapReq called successfully");
+ }
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG_HANDLER, "sendRilMessage: IllegalArgumentException", e);
+ sendClientMessage(new SapMessage(SapMessage.ID_ERROR_RESP));
+ } catch (RemoteException | RuntimeException e) {
+ Log.e(TAG_HANDLER, "sendRilMessage: Unable to send message to RIL: " + e);
+ sendClientMessage(new SapMessage(SapMessage.ID_ERROR_RESP));
+ mRilBtReceiver.notifyShutdown(); /* Only needed in case of a connection error */
+ mRilBtReceiver.resetSapProxy();
+ }
}
}