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

Commit 418f2282 authored by Amit Mahajan's avatar Amit Mahajan Committed by android-build-merger
Browse files

Merge "Remove SAP socket" am: 53dc5da3

am: a1cc2558

Change-Id: I792e0cf0f040a50f448b134b766bbe31ad8dbead
parents a2ccb14f a1cc2558
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.