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

Commit f72b0e44 authored by Eric Rowe's avatar Eric Rowe Committed by Android (Google) Code Review
Browse files

Merge "DO NOT MERGE Add A2DP and Headset connection stress tests." into gingerbread

parents f6639c46 66991b95
Loading
Loading
Loading
Loading
+551 −0
Original line number Diff line number Diff line
@@ -20,8 +20,10 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Set;

import android.app.Instrumentation;
import android.bluetooth.BluetoothHeadset.ServiceListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -59,6 +61,36 @@ public class BluetoothStressTest extends InstrumentationTestCase {
     */
    private static final int CANCEL_DISCOVERY_TIMEOUT = 5000;

    /**
     * Timeout for {@link BluetoothDevice#createBond()} in ms.
     */
    private static final int PAIR_TIMEOUT = 20000;

    /**
     * Timeout for {@link BluetoothDevice#removeBond()} in ms.
     */
    private static final int UNPAIR_TIMEOUT = 20000;

    /**
     * Timeout for {@link BluetoothA2dp#connectSink(BluetoothDevice)} in ms.
     */
    private static final int CONNECT_A2DP_TIMEOUT = 20000;

    /**
     * Timeout for {@link BluetoothA2dp#disconnectSink(BluetoothDevice)} in ms.
     */
    private static final int DISCONNECT_A2DP_TIMEOUT = 20000;

    /**
     * Timeout for {@link BluetoothHeadset#connectHeadset(BluetoothDevice)} in ms.
     */
    private static final int CONNECT_HEADSET_TIMEOUT = 20000;

    /**
     * Timeout for {@link BluetoothHeadset#disconnectHeadset(BluetoothDevice)} in ms.
     */
    private static final int DISCONNECT_HEADSET_TIMEOUT = 20000;

    private static final int DISCOVERY_STARTED_FLAG = 1;
    private static final int DISCOVERY_FINISHED_FLAG = 1 << 1;
    private static final int SCAN_MODE_NONE_FLAG = 1 << 2;
@@ -68,6 +100,23 @@ public class BluetoothStressTest extends InstrumentationTestCase {
    private static final int STATE_TURNING_ON_FLAG = 1 << 6;
    private static final int STATE_ON_FLAG = 1 << 7;
    private static final int STATE_TURNING_OFF_FLAG = 1 << 8;
    private static final int PAIR_STATE_FLAG = 1 << 9;
    private static final int PROFILE_A2DP_FLAG = 1 << 10;
    private static final int PROFILE_HEADSET_FLAG = 1 << 11;

    private static final int PAIR_STATE_BONDED = 1;
    private static final int PAIR_STATE_BONDING = 1 << 1;
    private static final int PAIR_STATE_NONE = 1 << 2;

    private static final int A2DP_STATE_DISCONNECTED = 1;
    private static final int A2DP_STATE_CONNECTING = 1 << 1;
    private static final int A2DP_STATE_CONNECTED = 1 << 2;
    private static final int A2DP_STATE_DISCONNECTING = 1 << 3;
    private static final int A2DP_STATE_PLAYING = 1 << 4;

    private static final int HEADSET_STATE_DISCONNECTED = 1;
    private static final int HEADSET_STATE_CONNECTING = 1 << 1;
    private static final int HEADSET_STATE_CONNECTED = 1 << 2;

    /**
     * Time between polls in ms.
@@ -80,8 +129,41 @@ public class BluetoothStressTest extends InstrumentationTestCase {

    private BufferedWriter mOutputWriter;

    private BluetoothA2dp mA2dp;

    private BluetoothHeadset mHeadset;

    private class HeadsetServiceListener implements ServiceListener {
        private boolean mConnected = false;

        @Override
        public void onServiceConnected() {
            synchronized (this) {
                mConnected = true;
            }
        }

        @Override
        public void onServiceDisconnected() {
            synchronized (this) {
                mConnected = false;
            }
        }

        public boolean isConnected() {
            synchronized (this) {
                return mConnected;
            }
        }
    }

    private HeadsetServiceListener mHeadsetServiceListener = new HeadsetServiceListener();

    private class BluetoothReceiver extends BroadcastReceiver {
        private int mFiredFlags = 0;
        private int mPairFiredFlags = 0;
        private int mA2dpFiredFlags = 0;
        private int mHeadsetFiredFlags = 0;

        @Override
        public void onReceive(Context context, Intent intent) {
@@ -123,6 +205,58 @@ public class BluetoothStressTest extends InstrumentationTestCase {
                            mFiredFlags |= STATE_TURNING_OFF_FLAG;
                            break;
                    }
                } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
                    mFiredFlags |= PAIR_STATE_FLAG;
                    int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
                    assertNotSame(state, -1);
                    switch (state) {
                        case BluetoothDevice.BOND_BONDED:
                            mPairFiredFlags |= PAIR_STATE_BONDED;
                            break;
                        case BluetoothDevice.BOND_BONDING:
                            mPairFiredFlags |= PAIR_STATE_BONDING;
                            break;
                        case BluetoothDevice.BOND_NONE:
                            mPairFiredFlags |= PAIR_STATE_NONE;
                            break;
                    }
                } else if (BluetoothA2dp.ACTION_SINK_STATE_CHANGED.equals(intent.getAction())) {
                    mFiredFlags |= PROFILE_A2DP_FLAG;
                    int state = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE, -1);
                    assertNotSame(state, -1);
                    switch (state) {
                        case BluetoothA2dp.STATE_DISCONNECTED:
                            mA2dpFiredFlags |= A2DP_STATE_DISCONNECTED;
                            break;
                        case BluetoothA2dp.STATE_CONNECTING:
                            mA2dpFiredFlags |= A2DP_STATE_CONNECTING;
                            break;
                        case BluetoothA2dp.STATE_CONNECTED:
                            mA2dpFiredFlags |= A2DP_STATE_CONNECTED;
                            break;
                        case BluetoothA2dp.STATE_DISCONNECTING:
                            mA2dpFiredFlags |= A2DP_STATE_DISCONNECTING;
                            break;
                        case BluetoothA2dp.STATE_PLAYING:
                            mA2dpFiredFlags |= A2DP_STATE_PLAYING;
                            break;
                    }
                } else if (BluetoothHeadset.ACTION_STATE_CHANGED.equals(intent.getAction())) {
                    mFiredFlags |= PROFILE_HEADSET_FLAG;
                    int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                            BluetoothHeadset.STATE_ERROR);
                    assertNotSame(state, BluetoothHeadset.STATE_ERROR);
                    switch (state) {
                        case BluetoothHeadset.STATE_DISCONNECTED:
                            mHeadsetFiredFlags |= HEADSET_STATE_DISCONNECTED;
                            break;
                        case BluetoothHeadset.STATE_CONNECTING:
                            mHeadsetFiredFlags |= HEADSET_STATE_CONNECTING;
                            break;
                        case BluetoothHeadset.STATE_CONNECTED:
                            mHeadsetFiredFlags |= HEADSET_STATE_CONNECTED;
                            break;
                    }
                }
            }
        }
@@ -133,9 +267,30 @@ public class BluetoothStressTest extends InstrumentationTestCase {
            }
        }

        public int getPairFiredFlags() {
            synchronized (this) {
                return mPairFiredFlags;
            }
        }

        public int getA2dpFiredFlags() {
            synchronized (this) {
                return mA2dpFiredFlags;
            }
        }

        public int getHeadsetFiredFlags() {
            synchronized (this) {
                return mHeadsetFiredFlags;
            }
        }

        public void resetFiredFlags() {
            synchronized (this) {
                mFiredFlags = 0;
                mPairFiredFlags = 0;
                mA2dpFiredFlags = 0;
                mHeadsetFiredFlags = 0;
            }
        }
    }
@@ -162,7 +317,13 @@ public class BluetoothStressTest extends InstrumentationTestCase {
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
        filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
        mContext.registerReceiver(mReceiver, filter);

        mA2dp = new BluetoothA2dp(mContext);
        mHeadset = new BluetoothHeadset(mContext, mHeadsetServiceListener);
    }

    @Override
@@ -219,6 +380,51 @@ public class BluetoothStressTest extends InstrumentationTestCase {
        disable(adapter);
    }

    public void testPair() {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sHeadsetAddress);

        enable(adapter);
        pair(adapter, device);
        unpair(adapter, device);
        disable(adapter);
    }

    public void testConnectA2dp() {
        int iterations = BluetoothTestRunner.sConnectA2dpIterations;
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sA2dpAddress);

        enable(adapter);
        pair(adapter, device);

        for (int i = 0; i < iterations; i++) {
            writeOutput("connectA2dp iteration " + (i + 1) + " of " + iterations);
            connectA2dp(adapter, device);
            disconnectA2dp(adapter, device);
        }

        // TODO: Unpair from device if device can accept pairing after unpairing
        disable(adapter);
    }

    public void testConnectHeadset() {
        int iterations = BluetoothTestRunner.sConnectHeadsetIterations;
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sHeadsetAddress);

        enable(adapter);
        pair(adapter, device);

        for (int i = 0; i < iterations; i++) {
            writeOutput("connectHeadset iteration " + (i + 1) + " of " + iterations);
            connectHeadset(adapter, device);
            disconnectHeadset(adapter, device);
        }

        disable(adapter);
    }

    private void disable(BluetoothAdapter adapter) {
        int mask = STATE_TURNING_OFF_FLAG | STATE_OFF_FLAG | SCAN_MODE_NONE_FLAG;
        mReceiver.resetFiredFlags();
@@ -457,6 +663,351 @@ public class BluetoothStressTest extends InstrumentationTestCase {

    }

    private void pair(BluetoothAdapter adapter, BluetoothDevice device) {
        int mask = PAIR_STATE_FLAG;
        int pairMask = PAIR_STATE_BONDING | PAIR_STATE_BONDED;
        mReceiver.resetFiredFlags();

        if (!adapter.isEnabled()) {
            fail("pair() bluetooth not enabled");
        }

        int state = device.getBondState();
        switch (state) {
            case BluetoothDevice.BOND_BONDED:
                assertTrue(adapter.getBondedDevices().contains(device));
                return;
            case BluetoothDevice.BOND_BONDING:
                // Don't check for received intents since we might have missed them.
                mask = pairMask = 0;
                break;
            case BluetoothDevice.BOND_NONE:
                assertFalse(adapter.getBondedDevices().contains(device));
                assertTrue(device.createBond());
                break;
            default:
                fail("pair() invalide state: state=" + state);
        }

        long s = System.currentTimeMillis();
        while (System.currentTimeMillis() - s < PAIR_TIMEOUT) {
            state = device.getBondState();
            if (state == BluetoothDevice.BOND_BONDED) {
                assertTrue(adapter.getBondedDevices().contains(device));
                if ((mReceiver.getFiredFlags() & mask) == mask
                        && (mReceiver.getPairFiredFlags() & pairMask) == pairMask) {
                    writeOutput(String.format("pair() completed in %d ms: device=%s",
                            (System.currentTimeMillis() - s), device));
                    return;
                }
            }
            sleep(POLL_TIME);
        }

        int firedFlags = mReceiver.getFiredFlags();
        int pairFiredFlags = mReceiver.getPairFiredFlags();
        mReceiver.resetFiredFlags();
        fail(String.format("pair() timeout: state=%d (expected %d), flags=0x%x (expected 0x%x), "
                + "pairFlags=0x%x (expected 0x%x)", state, BluetoothDevice.BOND_BONDED, firedFlags,
                mask, pairFiredFlags, pairMask));
    }

    private void unpair(BluetoothAdapter adapter, BluetoothDevice device) {
        int mask = PAIR_STATE_FLAG;
        int pairMask = PAIR_STATE_NONE;
        mReceiver.resetFiredFlags();

        if (!adapter.isEnabled()) {
            fail("unpair() bluetooth not enabled");
        }

        int state = device.getBondState();
        switch (state) {
            case BluetoothDevice.BOND_BONDED:
                assertTrue(adapter.getBondedDevices().contains(device));
                assertTrue(device.removeBond());
                break;
            case BluetoothDevice.BOND_BONDING:
                assertTrue(device.removeBond());
                break;
            case BluetoothDevice.BOND_NONE:
                assertFalse(adapter.getBondedDevices().contains(device));
                return;
            default:
                fail("unpair() invalid state: state=" + state);
        }

        assertTrue(device.removeBond());

        long s = System.currentTimeMillis();
        while (System.currentTimeMillis() - s < UNPAIR_TIMEOUT) {
            if (device.getBondState() == BluetoothDevice.BOND_NONE) {
                assertFalse(adapter.getBondedDevices().contains(device));
                if ((mReceiver.getFiredFlags() & mask) == mask
                        && (mReceiver.getPairFiredFlags() & pairMask) == pairMask) {
                    writeOutput(String.format("unpair() completed in %d ms: device=%s",
                            (System.currentTimeMillis() - s), device));
                    return;
                }
            }
        }

        int firedFlags = mReceiver.getFiredFlags();
        int pairFiredFlags = mReceiver.getPairFiredFlags();
        mReceiver.resetFiredFlags();
        fail(String.format("unpair() timeout: state=%d (expected %d), flags=0x%x (expected 0x%x), "
                + "pairFlags=0x%x (expected 0x%x)", state, BluetoothDevice.BOND_BONDED, firedFlags,
                mask, pairFiredFlags, pairMask));
    }

    private void connectA2dp(BluetoothAdapter adapter, BluetoothDevice device) {
        int mask = PROFILE_A2DP_FLAG;
        int a2dpMask1 = A2DP_STATE_CONNECTING | A2DP_STATE_CONNECTED | A2DP_STATE_PLAYING;
        int a2dpMask2 = a2dpMask1 ^ A2DP_STATE_CONNECTED;
        int a2dpMask3 = a2dpMask1 ^ A2DP_STATE_PLAYING;
        mReceiver.resetFiredFlags();

        if (!adapter.isEnabled()) {
            fail("connectA2dp() bluetooth not enabled");
        }

        if (!adapter.getBondedDevices().contains(device)) {
            fail("connectA2dp() device not paired: device=" + device);
        }

        int state = mA2dp.getSinkState(device);
        switch (state) {
            case BluetoothA2dp.STATE_CONNECTED:
            case BluetoothA2dp.STATE_PLAYING:
                assertTrue(mA2dp.isSinkConnected(device));
                return;
            case BluetoothA2dp.STATE_DISCONNECTING:
            case BluetoothA2dp.STATE_DISCONNECTED:
                assertFalse(mA2dp.isSinkConnected(device));
                assertTrue(mA2dp.connectSink(device));
                break;
            case BluetoothA2dp.STATE_CONNECTING:
                assertFalse(mA2dp.isSinkConnected(device));
                // Don't check for received intents since we might have missed them.
                mask = a2dpMask1 = a2dpMask2 = a2dpMask3 = 0;
                break;
            default:
                fail("connectA2dp() invalid state: state=" + state);
        }

        long s = System.currentTimeMillis();
        while (System.currentTimeMillis() - s < CONNECT_A2DP_TIMEOUT) {
            state = mA2dp.getSinkState(device);
            if (state == BluetoothA2dp.STATE_CONNECTED || state == BluetoothA2dp.STATE_PLAYING) {
                assertTrue(mA2dp.isSinkConnected(device));
                // Check whether STATE_CONNECTING and (STATE_CONNECTED or STATE_PLAYING) intents
                // have fired if we are checking if intents should be fired.
                int firedFlags = mReceiver.getFiredFlags();
                int a2dpFiredFlags = mReceiver.getA2dpFiredFlags();
                if ((mReceiver.getFiredFlags() & mask) == mask
                        && ((a2dpFiredFlags & a2dpMask1) == a2dpMask1
                                || (a2dpFiredFlags & a2dpMask2) == a2dpMask2
                                || (a2dpFiredFlags & a2dpMask3) == a2dpMask3)) {
                    mReceiver.resetFiredFlags();
                    writeOutput(String.format("connectA2dp() completed in %d ms: device=%s",
                            (System.currentTimeMillis() - s), device));
                    return;
                }
            }
            sleep(POLL_TIME);
        }

        int firedFlags = mReceiver.getFiredFlags();
        int a2dpFiredFlags = mReceiver.getA2dpFiredFlags();
        mReceiver.resetFiredFlags();
        fail(String.format("connectA2dp() timeout: state=%d (expected %d or %d), "
                + "flags=0x%x (expected 0x%x), a2dpFlags=0x%x (expected 0x%x or 0x%x or 0x%x)",
                state, BluetoothHeadset.STATE_CONNECTED, BluetoothA2dp.STATE_PLAYING, firedFlags,
                mask, a2dpFiredFlags, a2dpMask1, a2dpMask2, a2dpMask3));
    }

    private void disconnectA2dp(BluetoothAdapter adapter, BluetoothDevice device) {
        int mask = PROFILE_A2DP_FLAG;
        int a2dpMask = A2DP_STATE_DISCONNECTING | A2DP_STATE_DISCONNECTED;
        mReceiver.resetFiredFlags();

        if (!adapter.isEnabled()) {
            fail("disconnectA2dp() bluetooth not enabled");
        }

        if (!adapter.getBondedDevices().contains(device)) {
            fail("disconnectA2dp() device not paired: device=" + device);
        }

        int state = mA2dp.getSinkState(device);
        switch (state) {
            case BluetoothA2dp.STATE_DISCONNECTED:
                assertFalse(mA2dp.isSinkConnected(device));
                return;
            case BluetoothA2dp.STATE_CONNECTED:
            case BluetoothA2dp.STATE_PLAYING:
                assertTrue(mA2dp.isSinkConnected(device));
                assertTrue(mA2dp.disconnectSink(device));
                break;
            case BluetoothA2dp.STATE_CONNECTING:
                assertFalse(mA2dp.isSinkConnected(device));
                assertTrue(mA2dp.disconnectSink(device));
                break;
            case BluetoothA2dp.STATE_DISCONNECTING:
                assertFalse(mA2dp.isSinkConnected(device));
                // Don't check for received intents since we might have missed them.
                mask = a2dpMask = 0;
                break;
            default:
                fail("disconnectA2dp() invalid state: state=" + state);
        }

        long s = System.currentTimeMillis();
        while (System.currentTimeMillis() - s < DISCONNECT_A2DP_TIMEOUT) {
            state = mA2dp.getSinkState(device);
            if (state == BluetoothA2dp.STATE_DISCONNECTED) {
                assertFalse(mA2dp.isSinkConnected(device));
                if ((mReceiver.getFiredFlags() & mask) == mask
                        && (mReceiver.getA2dpFiredFlags() & a2dpMask) == a2dpMask) {
                    mReceiver.resetFiredFlags();
                    writeOutput(String.format("disconnectA2dp() completed in %d ms: device=%s",
                            (System.currentTimeMillis() - s), device));
                    return;
                }
            }
            sleep(POLL_TIME);
        }

        int firedFlags = mReceiver.getFiredFlags();
        int a2dpFiredFlags = mReceiver.getA2dpFiredFlags();
        mReceiver.resetFiredFlags();
        fail(String.format("disconnectA2dp() timeout: state=%d (expected %d), "
                + "flags=0x%x (expected 0x%x), a2dpFlags=0x%x (expected 0x%x)", state,
                BluetoothA2dp.STATE_DISCONNECTED, firedFlags, mask, a2dpFiredFlags, a2dpMask));
    }

    private void connectHeadset(BluetoothAdapter adapter, BluetoothDevice device) {
        int mask = PROFILE_HEADSET_FLAG;
        int headsetMask = HEADSET_STATE_CONNECTING | HEADSET_STATE_CONNECTED;
        mReceiver.resetFiredFlags();

        if (!adapter.isEnabled()) {
            fail("connectHeadset() bluetooth not enabled");
        }

        if (!adapter.getBondedDevices().contains(device)) {
            fail("connectHeadset() device not paired: device=" + device);
        }

        while (!mHeadsetServiceListener.isConnected()) {
            sleep(POLL_TIME);
        }

        int state = mHeadset.getState(device);
        switch (state) {
            case BluetoothHeadset.STATE_CONNECTED:
                assertTrue(mHeadset.isConnected(device));
                return;
            case BluetoothHeadset.STATE_DISCONNECTED:
                assertFalse(mHeadset.isConnected(device));
                mHeadset.connectHeadset(device);
                break;
            case BluetoothHeadset.STATE_CONNECTING:
                assertFalse(mHeadset.isConnected(device));
                // Don't check for received intents since we might have missed them.
                mask = headsetMask = 0;
                break;
            case BluetoothHeadset.STATE_ERROR:
                fail("connectHeadset() error state");
                break;
            default:
                fail("connectHeadset() invalid state: state=" + state);
        }

        long s = System.currentTimeMillis();
        while (System.currentTimeMillis() - s < CONNECT_HEADSET_TIMEOUT) {
            state = mHeadset.getState(device);
            if (state == BluetoothHeadset.STATE_CONNECTED) {
                assertTrue(mHeadset.isConnected(device));
                if ((mReceiver.getFiredFlags() & mask) == mask
                        && (mReceiver.getHeadsetFiredFlags() & headsetMask) == headsetMask) {
                    mReceiver.resetFiredFlags();
                    writeOutput(String.format("connectHeadset() completed in %d ms: device=%s",
                            (System.currentTimeMillis() - s), device));
                    return;
                }
            }
            sleep(POLL_TIME);
        }

        int firedFlags = mReceiver.getFiredFlags();
        int headsetFiredFlags = mReceiver.getHeadsetFiredFlags();
        mReceiver.resetFiredFlags();
        fail(String.format("connectHeadset() timeout: state=%d (expected %d), "
                + "flags=0x%x (expected 0x%x), headsetFlags=0x%s (expected 0x%x)", state,
                BluetoothHeadset.STATE_CONNECTED, firedFlags, mask, headsetFiredFlags,
                headsetMask));
    }

    private void disconnectHeadset(BluetoothAdapter adapter, BluetoothDevice device) {
        int mask = PROFILE_HEADSET_FLAG;
        int headsetMask = HEADSET_STATE_DISCONNECTED;
        mReceiver.resetFiredFlags();

        if (!adapter.isEnabled()) {
            fail("disconnectHeadset() bluetooth not enabled");
        }

        if (!adapter.getBondedDevices().contains(device)) {
            fail("disconnectHeadset() device not paired: device=" + device);
        }

        while (!mHeadsetServiceListener.isConnected()) {
            sleep(POLL_TIME);
        }

        int state = mHeadset.getState(device);
        switch (state) {
            case BluetoothHeadset.STATE_CONNECTED:
                mHeadset.disconnectHeadset(device);
                break;
            case BluetoothHeadset.STATE_CONNECTING:
                mHeadset.disconnectHeadset(device);
                break;
            case BluetoothHeadset.STATE_DISCONNECTED:
                return;
            case BluetoothHeadset.STATE_ERROR:
                fail("disconnectHeadset() error state");
                break;
            default:
                fail("disconnectHeadset() invalid state: state=" + state);
        }

        long s = System.currentTimeMillis();
        while (System.currentTimeMillis() - s < DISCONNECT_HEADSET_TIMEOUT) {
            state = mHeadset.getState(device);
            if (state == BluetoothHeadset.STATE_DISCONNECTED) {
                assertFalse(mHeadset.isConnected(device));
                if ((mReceiver.getFiredFlags() & mask) == mask
                        && (mReceiver.getHeadsetFiredFlags() & headsetMask) == headsetMask) {
                    mReceiver.resetFiredFlags();
                    writeOutput(String.format("disconnectHeadset() completed in %d ms: device=%s",
                            (System.currentTimeMillis() - s), device));
                    return;
                }
            }
            sleep(POLL_TIME);
        }

        int firedFlags = mReceiver.getFiredFlags();
        int headsetFiredFlags = mReceiver.getHeadsetFiredFlags();
        mReceiver.resetFiredFlags();
        fail(String.format("disconnectHeadset() timeout: state=%d (expected %d), "
                + "flags=0x%x (expected 0x%x), headsetFlags=0x%s (expected 0x%x)", state,
                BluetoothHeadset.STATE_DISCONNECTED, firedFlags, mask, headsetFiredFlags,
                headsetMask));
    }

    private void writeOutput(String s) {
        if (mOutputWriter == null) {
            return;
+33 −0

File changed.

Preview size limit exceeded, changes collapsed.