Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 887e2ab6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove SAP socket"

parents 593d303c db00ba3e
Loading
Loading
Loading
Loading
+50 −180
Original line number Diff line number Diff line
@@ -22,8 +22,7 @@ import android.os.Message;
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 @@ public class SapRilReceiver implements Runnable {
    // 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 class SapRilReceiver implements Runnable {
        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 class SapRilReceiver implements Runnable {

        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 class SapRilReceiver implements Runnable {
        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 class SapRilReceiver implements Runnable {

        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 class SapRilReceiver implements Runnable {

        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 class SapRilReceiver implements Runnable {

        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 class SapRilReceiver implements Runnable {

        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 class SapRilReceiver implements Runnable {

        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 @@ public class SapRilReceiver implements Runnable {
                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 class SapRilReceiver implements Runnable {

        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 class SapRilReceiver implements Runnable {

        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,7 +201,12 @@ public class SapRilReceiver implements Runnable {
        return ret;
    }

    public Object getSapProxyLock() {
        return mSapProxyLock;
    }

    public ISap getSapProxy() {
        synchronized (mSapProxyLock) {
            if (mSapProxy != null) {
                return mSapProxy;
            }
@@ -202,135 +214,53 @@ public class SapRilReceiver implements Runnable {
            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.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 service is not up, treat it like death notification to try to get service again
            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);

            Log.e(TAG, "getSapProxy: exception", e);
            }
            return mSapProxy;
        }
    }

    public void resetSapProxy() {
        synchronized (mSapProxyLock) {
            mSapProxy = null;
        }
    }

    public SapRilReceiver(Handler SapServerMsgHandler, Handler sapServiceHandler) {
        mSapServerMsgHandler = SapServerMsgHandler;
        mSapServiceHandler = sapServiceHandler;
        mSapCallback = new SapCallback();
        mSapProxyDeathRecipient = new SapProxyDeathRecipient();
        synchronized (mSapProxyLock) {
            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;
            }
        }
        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();
        }
    }

@@ -386,70 +316,10 @@ public class SapRilReceiver implements Runnable {
        return messageLength;
    }

    /**
     * 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);
        }
+29 −30
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ public class SapServer extends Thread implements Callback {
    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 @@ public class SapServer extends Thread implements Callback {
            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 @@ public class SapServer extends Thread implements Callback {
                mHandlerThread.join();
                mHandlerThread = null;
            } catch (InterruptedException e) {}
            if(mRilBtReceiverThread != null) try {
            if (mRilBtReceiver != null) {
                    mRilBtReceiver.shutdown();
                mRilBtReceiver.resetSapProxy();
                mRilBtReceiver = null;
            }
                mRilBtReceiverThread.join();
                mRilBtReceiverThread = null;
            } catch (InterruptedException e) {}

            if(mRfcommIn != null) try {
                if(VERBOSE) Log.i(TAG, "Closing mRfcommIn...");
@@ -521,9 +515,9 @@ public class SapServer extends Thread implements Callback {
                 *  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 @@ public class SapServer extends Thread implements Callback {
            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,9 +851,11 @@ public class SapServer extends Thread implements Callback {
                + SapMessage.getMsgTypeName(sapMsg.getMsgType()));

        Log.d(TAG_HANDLER, "sendRilMessage: calling getSapProxy");
        synchronized (mRilBtReceiver.getSapProxyLock()) {
            ISap sapProxy = mRilBtReceiver.getSapProxy();
            if (sapProxy == null) {
            Log.e(TAG_HANDLER, "sendRilMessage: Unable to send message to RIL; sapProxy is null");
                Log.e(TAG_HANDLER,
                        "sendRilMessage: Unable to send message to RIL; sapProxy is null");
                sendClientMessage(new SapMessage(SapMessage.ID_ERROR_RESP));
                return;
            }
@@ -872,11 +869,13 @@ public class SapServer extends Thread implements Callback {
                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);
                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();
            }
        }
    }

    /**
     * Only call this from the sapHandler thread.