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

Commit 7b91a410 authored by Zhihai Xu's avatar Zhihai Xu
Browse files

Null pointer exception in SocketAcceptThread of BluetoothPbapService.

issue 7650255

Change-Id: Ied5c4ba2b34ffef9edaaa1ad7d8b4a9a0e73ef90
parent f60d96d6
Loading
Loading
Loading
Loading
+57 −41
Original line number Original line Diff line number Diff line
@@ -297,10 +297,6 @@ public class BluetoothPbapService extends Service {


        super.onDestroy();
        super.onDestroy();
        setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED);
        setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED);
        if (mWakeLock != null) {
            mWakeLock.release();
            mWakeLock = null;
        }
        closeService();
        closeService();
        if(mSessionStatusHandler != null) {
        if(mSessionStatusHandler != null) {
            mSessionStatusHandler.removeCallbacksAndMessages(null);
            mSessionStatusHandler.removeCallbacksAndMessages(null);
@@ -326,11 +322,12 @@ public class BluetoothPbapService extends Service {
    private final boolean initSocket() {
    private final boolean initSocket() {
        if (VERBOSE) Log.v(TAG, "Pbap Service initSocket");
        if (VERBOSE) Log.v(TAG, "Pbap Service initSocket");


        boolean initSocketOK = true;
        boolean initSocketOK = false;
        final int CREATE_RETRY_TIME = 10;
        final int CREATE_RETRY_TIME = 10;


        // It's possible that create will fail in some cases. retry for 10 times
        // It's possible that create will fail in some cases. retry for 10 times
        for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) {
        for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) {
            initSocketOK = true;
            try {
            try {
                // It is mandatory for PSE to support initiation of bonding and
                // It is mandatory for PSE to support initiation of bonding and
                // encryption.
                // encryption.
@@ -350,20 +347,24 @@ public class BluetoothPbapService extends Service {
                    Log.w(TAG, "initServerSocket failed as BT is (being) turned off");
                    Log.w(TAG, "initServerSocket failed as BT is (being) turned off");
                    break;
                    break;
                }
                }
                synchronized (this) {
                try {
                try {
                    if (VERBOSE) Log.v(TAG, "wait 300 ms");
                    if (VERBOSE) Log.v(TAG, "wait 300 ms");
                    Thread.sleep(300);
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                    Log.e(TAG, "socketAcceptThread thread was interrupted (3)");
                    Log.e(TAG, "socketAcceptThread thread was interrupted (3)");
                        mInterrupted = true;
                    break;
                    }
                }
                }
            } else {
            } else {
                break;
                break;
            }
            }
        }
        }


        if (mInterrupted) {
            initSocketOK = false;
            // close server socket to avoid resource leakage
            closeServerSocket();
        }

        if (initSocketOK) {
        if (initSocketOK) {
            if (VERBOSE) Log.v(TAG, "Succeed to create listening socket ");
            if (VERBOSE) Log.v(TAG, "Succeed to create listening socket ");


@@ -373,21 +374,26 @@ public class BluetoothPbapService extends Service {
        return initSocketOK;
        return initSocketOK;
    }
    }


    private final void closeSocket(boolean server, boolean accept) throws IOException {
    private final synchronized void closeServerSocket() {
        if (server == true) {
        // exit SocketAcceptThread early
            // Stop the possible trying to init serverSocket
            mInterrupted = true;

        if (mServerSocket != null) {
        if (mServerSocket != null) {
            try {
                // this will cause mServerSocket.accept() return early with IOException
                mServerSocket.close();
                mServerSocket.close();
                mServerSocket = null;
                mServerSocket = null;
            } catch (IOException ex) {
                Log.e(TAG, "Close Server Socket error: " + ex);
            }
        }
        }
    }
    }


        if (accept == true) {
    private final synchronized void closeConnectionSocket() {
        if (mConnSocket != null) {
        if (mConnSocket != null) {
            try {
                mConnSocket.close();
                mConnSocket.close();
                mConnSocket = null;
                mConnSocket = null;
            } catch (IOException e) {
                Log.e(TAG, "Close Connection Socket error: " + e.toString());
            }
            }
        }
        }
    }
    }
@@ -395,11 +401,9 @@ public class BluetoothPbapService extends Service {
    private final void closeService() {
    private final void closeService() {
        if (VERBOSE) Log.v(TAG, "Pbap Service closeService in");
        if (VERBOSE) Log.v(TAG, "Pbap Service closeService in");


        try {
        // exit initSocket early
            closeSocket(true, true);
        mInterrupted = true;
        } catch (IOException ex) {
        closeServerSocket();
            Log.e(TAG, "CloseSocket error: " + ex);
        }


        if (mAcceptThread != null) {
        if (mAcceptThread != null) {
            try {
            try {
@@ -410,11 +414,19 @@ public class BluetoothPbapService extends Service {
                Log.w(TAG, "mAcceptThread close error" + ex);
                Log.w(TAG, "mAcceptThread close error" + ex);
            }
            }
        }
        }

        if (mWakeLock != null) {
            mWakeLock.release();
            mWakeLock = null;
        }

        if (mServerSession != null) {
        if (mServerSession != null) {
            mServerSession.close();
            mServerSession.close();
            mServerSession = null;
            mServerSession = null;
        }
        }


        closeConnectionSocket();

        mHasStarted = false;
        mHasStarted = false;
        if (mStartId != -1 && stopSelfResult(mStartId)) {
        if (mStartId != -1 && stopSelfResult(mStartId)) {
            if (VERBOSE) Log.v(TAG, "successfully stopped pbap service");
            if (VERBOSE) Log.v(TAG, "successfully stopped pbap service");
@@ -473,12 +485,8 @@ public class BluetoothPbapService extends Service {


        mAcceptThread = null;
        mAcceptThread = null;


        try {
        closeConnectionSocket();
            closeSocket(false, true);

	    mConnSocket = null;
        } catch (IOException e) {
            Log.e(TAG, "closeSocket error: " + e.toString());
        }
        // Last obex transaction is finished, we start to listen for incoming
        // Last obex transaction is finished, we start to listen for incoming
        // connection again
        // connection again
        if (mAdapter.isEnabled()) {
        if (mAdapter.isEnabled()) {
@@ -516,9 +524,9 @@ public class BluetoothPbapService extends Service {


        @Override
        @Override
        public void run() {
        public void run() {
            BluetoothServerSocket serverSocket;
            if (mServerSocket == null) {
            if (mServerSocket == null) {
                if (!initSocket()) {
                if (!initSocket()) {
                    closeService();
                    return;
                    return;
                }
                }
            }
            }
@@ -526,10 +534,21 @@ public class BluetoothPbapService extends Service {
            while (!stopped) {
            while (!stopped) {
                try {
                try {
                    if (VERBOSE) Log.v(TAG, "Accepting socket connection...");
                    if (VERBOSE) Log.v(TAG, "Accepting socket connection...");
                    mConnSocket = mServerSocket.accept();
                    serverSocket = mServerSocket;
                    if (serverSocket == null) {
                        Log.w(TAG, "mServerSocket is null");
                        break;
                    }
                    mConnSocket = serverSocket.accept();
                    if (VERBOSE) Log.v(TAG, "Accepted socket connection...");
                    if (VERBOSE) Log.v(TAG, "Accepted socket connection...");


                    synchronized (BluetoothPbapService.this) {
                        if (mConnSocket == null) {
                            Log.w(TAG, "mConnSocket is null");
                            break;
                        }
                        mRemoteDevice = mConnSocket.getRemoteDevice();
                        mRemoteDevice = mConnSocket.getRemoteDevice();
                    }
                    if (mRemoteDevice == null) {
                    if (mRemoteDevice == null) {
                        Log.i(TAG, "getRemoteDevice() = null");
                        Log.i(TAG, "getRemoteDevice() = null");
                        break;
                        break;
@@ -783,12 +802,9 @@ public class BluetoothPbapService extends Service {
                            mServerSession.close();
                            mServerSession.close();
                            mServerSession = null;
                            mServerSession = null;
                        }
                        }
                        try {

                            closeSocket(false, true);
                        closeConnectionSocket();
                            mConnSocket = null;

                        } catch (IOException ex) {
                            Log.e(TAG, "Caught the error: " + ex);
                        }
                        setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED);
                        setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED);
                        break;
                        break;
                    default:
                    default: