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

Commit e46503b4 authored by Sungsoo Lim's avatar Sungsoo Lim
Browse files

Avoid potential NPE of mHandlerThread.getLooper()

mHandlerThread can be accessed by multiple thread and if it is quited
right after started, mHandlerThread.getLooper() will return null which
caused a null pointer exception.

Bug: 273396169
Test: atest BluetoothIntrumentationTests:PbapClientServiceTest 1000 times
Change-Id: I77ab6d5ec08715c80b40b4e8c28c035753b6dced
parent 82ce0208
Loading
Loading
Loading
Loading
+38 −14
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.Process;
@@ -166,17 +167,18 @@ class PbapClientStateMachine extends StateMachine {
            mHandlerThread =
                    new HandlerThread("PBAP PCE handler", Process.THREAD_PRIORITY_BACKGROUND);
            mHandlerThread.start();
            Looper looper = mHandlerThread.getLooper();

            // Keeps mock handler from being overwritten in tests
            if (mConnectionHandler == null) {
            if (mConnectionHandler == null && looper != null) {
                mConnectionHandler =
                    new PbapClientConnectionHandler.Builder().setLooper(mHandlerThread.getLooper())
                        new PbapClientConnectionHandler.Builder()
                                .setLooper(looper)
                                .setContext(mService)
                                .setClientSM(PbapClientStateMachine.this)
                                .setRemoteDevice(mCurrentDevice)
                                .build();
            }

            sendMessageDelayed(MSG_CONNECT_TIMEOUT, CONNECT_TIMEOUT);
        }

@@ -206,8 +208,12 @@ class PbapClientStateMachine extends StateMachine {
                    break;

                case MSG_SDP_COMPLETE:
                    mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_CONNECT,
                            message.obj).sendToTarget();
                    PbapClientConnectionHandler connectionHandler = mConnectionHandler;
                    if (connectionHandler != null) {
                        connectionHandler
                                .obtainMessage(PbapClientConnectionHandler.MSG_CONNECT, message.obj)
                                .sendToTarget();
                    }
                    break;

                default:
@@ -269,8 +275,12 @@ class PbapClientStateMachine extends StateMachine {
            onConnectionStateChanged(mCurrentDevice, mMostRecentState,
                    BluetoothProfile.STATE_DISCONNECTING);
            mMostRecentState = BluetoothProfile.STATE_DISCONNECTING;
            mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DISCONNECT)
            PbapClientConnectionHandler connectionHandler = mConnectionHandler;
            if (connectionHandler != null) {
                connectionHandler
                        .obtainMessage(PbapClientConnectionHandler.MSG_DISCONNECT)
                        .sendToTarget();
            }
            sendMessageDelayed(MSG_DISCONNECT_TIMEOUT, DISCONNECT_TIMEOUT);
        }

@@ -292,7 +302,10 @@ class PbapClientStateMachine extends StateMachine {

                case MSG_DISCONNECT_TIMEOUT:
                    Log.w(TAG, "Disconnect Timeout, Forcing");
                    mConnectionHandler.abort();
                    PbapClientConnectionHandler connectionHandler = mConnectionHandler;
                    if (connectionHandler != null) {
                        connectionHandler.abort();
                    }
                    mHandlerThread.quitSafely();
                    transitionTo(mDisconnected);
                    break;
@@ -355,9 +368,13 @@ class PbapClientStateMachine extends StateMachine {
                    + ", accountServiceReady=" + accountServiceReady);
            return;
        }
        mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD)
        PbapClientConnectionHandler connectionHandler = mConnectionHandler;
        if (connectionHandler != null) {
            connectionHandler
                    .obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD)
                    .sendToTarget();
        }
    }

    private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
        if (device == null) {
@@ -388,8 +405,15 @@ class PbapClientStateMachine extends StateMachine {
    }

    void doQuit() {
        PbapClientConnectionHandler connectionHandler = mConnectionHandler;
        if (connectionHandler != null) {
            connectionHandler.abort();
            mConnectionHandler = null;
        }

        if (mHandlerThread != null) {
            mHandlerThread.quitSafely();
            mHandlerThread = null;
        }
        quitNow();
    }
+0 −1
Original line number Diff line number Diff line
@@ -165,7 +165,6 @@ public class PbapClientServiceTest {
        assertThat(mService.connect(mRemoteDevice)).isFalse();
    }

    @Ignore("b/273396169")
    @Test
    public void testConnect_whenPolicyIsAllowed_returnsTrue() {
        int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED;