1185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe/* 2185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * Copyright (C) 2010 The Android Open Source Project 3185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * 4185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * Licensed under the Apache License, Version 2.0 (the "License"); 5185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * you may not use this file except in compliance with the License. 6185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * You may obtain a copy of the License at 7185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * 8185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * http://www.apache.org/licenses/LICENSE-2.0 9185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * 10185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * Unless required by applicable law or agreed to in writing, software 11185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * distributed under the License is distributed on an "AS IS" BASIS, 12185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * See the License for the specific language governing permissions and 14185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe * limitations under the License. 15185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe */ 16185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 17185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowepackage android.bluetooth; 18185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 1974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganeshimport android.bluetooth.BluetoothPan; 2074ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganeshimport android.bluetooth.BluetoothProfile; 21185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport android.content.BroadcastReceiver; 22185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport android.content.Context; 23185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport android.content.Intent; 24185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport android.content.IntentFilter; 25835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Roweimport android.media.AudioManager; 26185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport android.os.Environment; 27185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport android.util.Log; 28185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 29185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport junit.framework.Assert; 30185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 31185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport java.io.BufferedWriter; 32185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport java.io.File; 33185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport java.io.FileWriter; 34185a0b04c611a287cbd866d27b0ceff77f12d97bEric Roweimport java.io.IOException; 35826af6266c79d76b81fe850b9cd3d351597e4adbEric Roweimport java.util.ArrayList; 36826af6266c79d76b81fe850b9cd3d351597e4adbEric Roweimport java.util.List; 3703800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhuimport java.util.Set; 38f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavatiimport java.util.concurrent.Semaphore; 39f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavatiimport java.util.concurrent.TimeUnit; 40185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 41185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowepublic class BluetoothTestUtils extends Assert { 42185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 432b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe /** Timeout for enable/disable in ms. */ 44207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe private static final int ENABLE_DISABLE_TIMEOUT = 20000; 452b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe /** Timeout for discoverable/undiscoverable in ms. */ 46207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe private static final int DISCOVERABLE_UNDISCOVERABLE_TIMEOUT = 5000; 472b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe /** Timeout for starting/stopping a scan in ms. */ 48207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe private static final int START_STOP_SCAN_TIMEOUT = 5000; 492b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe /** Timeout for pair/unpair in ms. */ 50207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe private static final int PAIR_UNPAIR_TIMEOUT = 20000; 512b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe /** Timeout for connecting/disconnecting a profile in ms. */ 52207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe private static final int CONNECT_DISCONNECT_PROFILE_TIMEOUT = 20000; 532b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe /** Timeout to start or stop a SCO channel in ms. */ 54835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe private static final int START_STOP_SCO_TIMEOUT = 10000; 552b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe /** Timeout to connect a profile proxy in ms. */ 562b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe private static final int CONNECT_PROXY_TIMEOUT = 5000; 572b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe /** Time between polls in ms. */ 58185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe private static final int POLL_TIME = 100; 59185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 60826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private abstract class FlagReceiver extends BroadcastReceiver { 61826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private int mExpectedFlags = 0; 62826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private int mFiredFlags = 0; 63826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private long mCompletedTime = -1; 64185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 65826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public FlagReceiver(int expectedFlags) { 66826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mExpectedFlags = expectedFlags; 67826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 68185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 69826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public int getFiredFlags() { 70826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe synchronized (this) { 71826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return mFiredFlags; 72826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 73826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 74185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 75826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public long getCompletedTime() { 76826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe synchronized (this) { 77826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return mCompletedTime; 78826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 79826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 80826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 81826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe protected void setFiredFlag(int flag) { 82826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe synchronized (this) { 83826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mFiredFlags |= flag; 845d0ed7b952667a1506585683c9eb5fe5ed7f0af2Eric Rowe if ((mFiredFlags & mExpectedFlags) == mExpectedFlags) { 85826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mCompletedTime = System.currentTimeMillis(); 86826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 87826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 88826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 89826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 90826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 91826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private class BluetoothReceiver extends FlagReceiver { 92826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int DISCOVERY_STARTED_FLAG = 1; 93826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int DISCOVERY_FINISHED_FLAG = 1 << 1; 94826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int SCAN_MODE_NONE_FLAG = 1 << 2; 95826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int SCAN_MODE_CONNECTABLE_FLAG = 1 << 3; 96826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG = 1 << 4; 97826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_OFF_FLAG = 1 << 5; 98826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_TURNING_ON_FLAG = 1 << 6; 99826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_ON_FLAG = 1 << 7; 100826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_TURNING_OFF_FLAG = 1 << 8; 101826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 102826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public BluetoothReceiver(int expectedFlags) { 103826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe super(expectedFlags); 104826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 105185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 106185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe @Override 107185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void onReceive(Context context, Intent intent) { 108826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())) { 109826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(DISCOVERY_STARTED_FLAG); 110826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) { 111826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(DISCOVERY_FINISHED_FLAG); 112826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } else if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(intent.getAction())) { 113826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, -1); 114826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertNotSame(-1, mode); 115826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (mode) { 116826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothAdapter.SCAN_MODE_NONE: 117826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(SCAN_MODE_NONE_FLAG); 118826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 119826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 120826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(SCAN_MODE_CONNECTABLE_FLAG); 121826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 122826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 123826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG); 124826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 125826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 126826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) { 127826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 128826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertNotSame(-1, state); 129826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (state) { 130826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothAdapter.STATE_OFF: 131826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_OFF_FLAG); 132826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 133826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothAdapter.STATE_TURNING_ON: 134826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_TURNING_ON_FLAG); 135826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 136826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothAdapter.STATE_ON: 137826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_ON_FLAG); 138826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 139826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothAdapter.STATE_TURNING_OFF: 140826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_TURNING_OFF_FLAG); 141826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 142185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 143185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 144185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 145826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 146185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 147826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private class PairReceiver extends FlagReceiver { 148826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_BONDED_FLAG = 1; 149826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_BONDING_FLAG = 1 << 1; 150826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_NONE_FLAG = 1 << 2; 151826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 152826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private BluetoothDevice mDevice; 153826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private int mPasskey; 154826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private byte[] mPin; 155826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 156826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public PairReceiver(BluetoothDevice device, int passkey, byte[] pin, int expectedFlags) { 157826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe super(expectedFlags); 158826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 159826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mDevice = device; 160826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mPasskey = passkey; 161826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mPin = pin; 162826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 163826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 164826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe @Override 165826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public void onReceive(Context context, Intent intent) { 166826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) { 167826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return; 168826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 169826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 170826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(intent.getAction())) { 171826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int varient = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, -1); 172826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertNotSame(-1, varient); 173b49aa60829ab8fadec2f4c0661271100691d8225Eric Rowe switch (varient) { 174826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.PAIRING_VARIANT_PIN: 1753b3d1fea94318a4892fbd4353269749af417a81aCasper Bonde case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS: 176826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mDevice.setPin(mPin); 177826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 178826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.PAIRING_VARIANT_PASSKEY: 179826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mDevice.setPasskey(mPasskey); 180826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 181826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION: 182826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.PAIRING_VARIANT_CONSENT: 183826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mDevice.setPairingConfirmation(true); 184826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 185826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT: 186826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mDevice.setRemoteOutOfBandData(); 187826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 188826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 189826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) { 190826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1); 191826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertNotSame(-1, state); 192826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (state) { 193826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_NONE: 194826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_NONE_FLAG); 195826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 196826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_BONDING: 197826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_BONDING_FLAG); 198826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 199826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_BONDED: 200826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_BONDED_FLAG); 201826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 202826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 203826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 204826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 205826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 206826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 207826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private class ConnectProfileReceiver extends FlagReceiver { 208826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_DISCONNECTED_FLAG = 1; 209826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_CONNECTING_FLAG = 1 << 1; 210826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_CONNECTED_FLAG = 1 << 2; 211826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private static final int STATE_DISCONNECTING_FLAG = 1 << 3; 212826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 213826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private BluetoothDevice mDevice; 214826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private int mProfile; 215826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private String mConnectionAction; 216826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 217826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public ConnectProfileReceiver(BluetoothDevice device, int profile, int expectedFlags) { 218826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe super(expectedFlags); 219826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 220826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mDevice = device; 221826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mProfile = profile; 222826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 223b49aa60829ab8fadec2f4c0661271100691d8225Eric Rowe switch (mProfile) { 224826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.A2DP: 225826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mConnectionAction = BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED; 226826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 227826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.HEADSET: 228826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mConnectionAction = BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED; 229826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 230c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang case BluetoothProfile.HID_HOST: 231c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang mConnectionAction = BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED; 2324ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh break; 2332b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe case BluetoothProfile.PAN: 2342b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe mConnectionAction = BluetoothPan.ACTION_CONNECTION_STATE_CHANGED; 2352b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe break; 236826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe default: 237826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mConnectionAction = null; 238826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 239826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 240826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 241826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe @Override 242826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public void onReceive(Context context, Intent intent) { 243826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (mConnectionAction != null && mConnectionAction.equals(intent.getAction())) { 244826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) { 245826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return; 246826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 247826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 248826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); 249826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertNotSame(-1, state); 250826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (state) { 251826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_DISCONNECTED: 252826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_DISCONNECTED_FLAG); 253826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 254826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_CONNECTING: 255826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_CONNECTING_FLAG); 256826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 257826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_CONNECTED: 258826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_CONNECTED_FLAG); 259826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 260826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_DISCONNECTING: 261826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe setFiredFlag(STATE_DISCONNECTING_FLAG); 262826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 263826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 264826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 265826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 266826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 267826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 2682b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe private class ConnectPanReceiver extends ConnectProfileReceiver { 2697e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe private int mRole; 2707e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 2717e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe public ConnectPanReceiver(BluetoothDevice device, int role, int expectedFlags) { 2722b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe super(device, BluetoothProfile.PAN, expectedFlags); 2737e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 2747e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe mRole = role; 2757e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 2767e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 2777e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe @Override 2787e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe public void onReceive(Context context, Intent intent) { 2792b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (mRole != intent.getIntExtra(BluetoothPan.EXTRA_LOCAL_ROLE, -1)) { 2807e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe return; 2817e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 2827e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 2832b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe super.onReceive(context, intent); 2847e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 2857e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 2867e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 287835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe private class StartStopScoReceiver extends FlagReceiver { 288835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe private static final int STATE_CONNECTED_FLAG = 1; 289835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe private static final int STATE_DISCONNECTED_FLAG = 1 << 1; 290835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 291835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe public StartStopScoReceiver(int expectedFlags) { 292835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe super(expectedFlags); 293835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 294835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 295835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe @Override 296835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe public void onReceive(Context context, Intent intent) { 2977af75afb2c8608dbe73509036eefd3281d646a5fEric Rowe if (AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED.equals(intent.getAction())) { 298835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 299835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe AudioManager.SCO_AUDIO_STATE_ERROR); 300835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe assertNotSame(AudioManager.SCO_AUDIO_STATE_ERROR, state); 301835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe switch(state) { 302835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe case AudioManager.SCO_AUDIO_STATE_CONNECTED: 303835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe setFiredFlag(STATE_CONNECTED_FLAG); 304835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe break; 305835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe case AudioManager.SCO_AUDIO_STATE_DISCONNECTED: 306835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe setFiredFlag(STATE_DISCONNECTED_FLAG); 307835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe break; 308835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 309835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 310835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 311835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 312835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 313826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private BluetoothProfile.ServiceListener mServiceListener = 314826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe new BluetoothProfile.ServiceListener() { 3152b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe @Override 316826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public void onServiceConnected(int profile, BluetoothProfile proxy) { 317185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe synchronized (this) { 318826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (profile) { 319826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.A2DP: 320826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mA2dp = (BluetoothA2dp) proxy; 321826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 322826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.HEADSET: 323826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mHeadset = (BluetoothHeadset) proxy; 324826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 325c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang case BluetoothProfile.HID_HOST: 326c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang mInput = (BluetoothHidHost) proxy; 3274ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh break; 32874ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh case BluetoothProfile.PAN: 32974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh mPan = (BluetoothPan) proxy; 33074ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh break; 331826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 332185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 333185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 334185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 3352b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe @Override 336826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public void onServiceDisconnected(int profile) { 337185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe synchronized (this) { 338826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (profile) { 339826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.A2DP: 340826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mA2dp = null; 341826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 342826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.HEADSET: 343826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mHeadset = null; 344826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 345c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang case BluetoothProfile.HID_HOST: 3464ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh mInput = null; 3474ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh break; 34874ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh case BluetoothProfile.PAN: 34974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh mPan = null; 35074ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh break; 351826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 352185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 353185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 354826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe }; 355826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 356826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private List<BroadcastReceiver> mReceivers = new ArrayList<BroadcastReceiver>(); 357826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 358826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private BufferedWriter mOutputWriter; 359826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private String mTag; 360826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private String mOutputFile; 361185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 362826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private Context mContext; 3632b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe private BluetoothA2dp mA2dp = null; 3642b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe private BluetoothHeadset mHeadset = null; 365c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang private BluetoothHidHost mInput = null; 3662b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe private BluetoothPan mPan = null; 367185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 3687e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 3697e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Creates a utility instance for testing Bluetooth. 3707e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 3717e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param context The context of the application using the utility. 3727e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param tag The log tag of the application using the utility. 3737e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 374185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public BluetoothTestUtils(Context context, String tag) { 375185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe this(context, tag, null); 376185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 377185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 3787e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 3797e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Creates a utility instance for testing Bluetooth. 3807e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 3817e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param context The context of the application using the utility. 3827e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param tag The log tag of the application using the utility. 3837e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param outputFile The path to an output file if the utility is to write results to a 3847e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * separate file. 3857e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 386185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public BluetoothTestUtils(Context context, String tag, String outputFile) { 387185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mContext = context; 388185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mTag = tag; 389185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mOutputFile = outputFile; 390185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 391185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (mOutputFile == null) { 392185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mOutputWriter = null; 393185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } else { 394185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe try { 395185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mOutputWriter = new BufferedWriter(new FileWriter(new File( 396185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe Environment.getExternalStorageDirectory(), mOutputFile), true)); 397185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } catch (IOException e) { 398185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe Log.w(mTag, "Test output file could not be opened", e); 399185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mOutputWriter = null; 400185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 401185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 402185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 403185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 4047e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 4057e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Closes the utility instance and unregisters any BroadcastReceivers. 4067e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 407185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void close() { 408826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe while (!mReceivers.isEmpty()) { 409826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mContext.unregisterReceiver(mReceivers.remove(0)); 410826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 411185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 412185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (mOutputWriter != null) { 413185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe try { 414185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mOutputWriter.close(); 415185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } catch (IOException e) { 416185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe Log.w(mTag, "Test output file could not be closed", e); 417185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 418185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 419185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 420185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 4217e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 4227e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Enables Bluetooth and checks to make sure that Bluetooth was turned on and that the correct 4237e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * actions were broadcast. 4247e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 4257e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 4267e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 427185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void enable(BluetoothAdapter adapter) { 4286570340f713d0c716ce4860f6f43d1efa230242aSharvil Nanavati writeOutput("Enabling Bluetooth adapter."); 4296570340f713d0c716ce4860f6f43d1efa230242aSharvil Nanavati assertFalse(adapter.isEnabled()); 430571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou int btState = adapter.getState(); 431571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final Semaphore completionSemaphore = new Semaphore(0); 432571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final BroadcastReceiver receiver = new BroadcastReceiver() { 433571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou @Override 434571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou public void onReceive(Context context, Intent intent) { 435571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final String action = intent.getAction(); 436571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { 437571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou return; 438571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou } 439571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 440571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou BluetoothAdapter.ERROR); 441571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou if (state == BluetoothAdapter.STATE_ON) { 442571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou completionSemaphore.release(); 443185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 444185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 445571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou }; 446185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 447571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 448571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou mContext.registerReceiver(receiver, filter); 449571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou assertTrue(adapter.enable()); 450571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou boolean success = false; 451571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou try { 452571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou success = completionSemaphore.tryAcquire(ENABLE_DISABLE_TIMEOUT, TimeUnit.MILLISECONDS); 453571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou writeOutput(String.format("enable() completed in 0 ms")); 454571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou } catch (final InterruptedException e) { 455571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou // This should never happen but just in case it does, the test will fail anyway. 456571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou } 457571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou mContext.unregisterReceiver(receiver); 458571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou if (!success) { 459571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou fail(String.format("enable() timeout: state=%d (expected %d)", btState, 460571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou BluetoothAdapter.STATE_ON)); 461571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou } 462185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 463185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 4647e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 4657e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Disables Bluetooth and checks to make sure that Bluetooth was turned off and that the correct 4667e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * actions were broadcast. 4677e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 4687e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 4697e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 470185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void disable(BluetoothAdapter adapter) { 4716570340f713d0c716ce4860f6f43d1efa230242aSharvil Nanavati writeOutput("Disabling Bluetooth adapter."); 4726570340f713d0c716ce4860f6f43d1efa230242aSharvil Nanavati assertTrue(adapter.isEnabled()); 473571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou int btState = adapter.getState(); 474571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final Semaphore completionSemaphore = new Semaphore(0); 475571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final BroadcastReceiver receiver = new BroadcastReceiver() { 476571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou @Override 477571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou public void onReceive(Context context, Intent intent) { 478571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final String action = intent.getAction(); 479571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { 480571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou return; 481571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou } 482571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 483571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou BluetoothAdapter.ERROR); 484571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou if (state == BluetoothAdapter.STATE_OFF) { 485571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou completionSemaphore.release(); 486185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 487185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 488571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou }; 489185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 490571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou final IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 491571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou mContext.registerReceiver(receiver, filter); 492571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou assertTrue(adapter.disable()); 493571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou boolean success = false; 494571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou try { 495571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou success = completionSemaphore.tryAcquire(ENABLE_DISABLE_TIMEOUT, TimeUnit.MILLISECONDS); 496571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou writeOutput(String.format("disable() completed in 0 ms")); 497571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou } catch (final InterruptedException e) { 498571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou // This should never happen but just in case it does, the test will fail anyway. 499571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou } 500571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou mContext.unregisterReceiver(receiver); 501571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou if (!success) { 502571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou fail(String.format("disable() timeout: state=%d (expected %d)", btState, 503571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou BluetoothAdapter.STATE_OFF)); 504571a4a97cde06766921335d352fdff2a7b335a58Yuchao Zhou } 505185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 506185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 5077e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 5087e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Puts the local device into discoverable mode and checks to make sure that the local device 5097e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * is in discoverable mode and that the correct actions were broadcast. 5107e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 5117e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 5127e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 513185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void discoverable(BluetoothAdapter adapter) { 514185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (!adapter.isEnabled()) { 515185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe fail("discoverable() bluetooth not enabled"); 516185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 517185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 518185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe int scanMode = adapter.getScanMode(); 519f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati if (scanMode != BluetoothAdapter.SCAN_MODE_CONNECTABLE) { 520185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe return; 521185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 522185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 523f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final Semaphore completionSemaphore = new Semaphore(0); 524f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final BroadcastReceiver receiver = new BroadcastReceiver() { 525f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati @Override 526f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati public void onReceive(Context context, Intent intent) { 527f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final String action = intent.getAction(); 528f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati if (!BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) { 529f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati return; 530f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } 531f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, 532f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati BluetoothAdapter.SCAN_MODE_NONE); 533f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { 534f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati completionSemaphore.release(); 535f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } 536f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } 537f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati }; 538826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 539f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); 540f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati mContext.registerReceiver(receiver, filter); 541185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)); 542f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati boolean success = false; 543f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati try { 544f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati success = completionSemaphore.tryAcquire(DISCOVERABLE_UNDISCOVERABLE_TIMEOUT, 545f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati TimeUnit.MILLISECONDS); 546957abc831866470c5344750d70d2462e8676c4a7Sharvil Nanavati writeOutput(String.format("discoverable() completed in 0 ms")); 547f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } catch (final InterruptedException e) { 548f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati // This should never happen but just in case it does, the test will fail anyway. 549f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } 550f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati mContext.unregisterReceiver(receiver); 551f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati if (!success) { 552f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati fail(String.format("discoverable() timeout: scanMode=%d (expected %d)", scanMode, 553f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)); 554185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 555185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 556185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 5577e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 5587e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Puts the local device into connectable only mode and checks to make sure that the local 5597e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * device is in in connectable mode and that the correct actions were broadcast. 5607e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 5617e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 5627e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 563185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void undiscoverable(BluetoothAdapter adapter) { 564185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (!adapter.isEnabled()) { 565185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe fail("undiscoverable() bluetooth not enabled"); 566185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 567185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 568185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe int scanMode = adapter.getScanMode(); 569f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati if (scanMode != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { 570185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe return; 571185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 572185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 573f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final Semaphore completionSemaphore = new Semaphore(0); 574f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final BroadcastReceiver receiver = new BroadcastReceiver() { 575f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati @Override 576f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati public void onReceive(Context context, Intent intent) { 577f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final String action = intent.getAction(); 578f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati if (!BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) { 579f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati return; 580f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } 581f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, 582f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati BluetoothAdapter.SCAN_MODE_NONE); 583f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE) { 584f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati completionSemaphore.release(); 585f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } 586f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } 587f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati }; 588826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 589f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati final IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); 590f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati mContext.registerReceiver(receiver, filter); 591185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE)); 592f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati boolean success = false; 593f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati try { 594f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati success = completionSemaphore.tryAcquire(DISCOVERABLE_UNDISCOVERABLE_TIMEOUT, 595f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati TimeUnit.MILLISECONDS); 596957abc831866470c5344750d70d2462e8676c4a7Sharvil Nanavati writeOutput(String.format("undiscoverable() completed in 0 ms")); 597f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } catch (InterruptedException e) { 598f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati // This should never happen but just in case it does, the test will fail anyway. 599f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati } 600f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati mContext.unregisterReceiver(receiver); 601f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati if (!success) { 602f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati fail(String.format("undiscoverable() timeout: scanMode=%d (expected %d)", scanMode, 603f6aebbe4bd8a1999383b3eb485bf5d21ec5867d8Sharvil Nanavati BluetoothAdapter.SCAN_MODE_CONNECTABLE)); 604185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 605185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 606185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 6077e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 6087e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Starts a scan for remote devices and checks to make sure that the local device is scanning 6097e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * and that the correct actions were broadcast. 6107e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 6117e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 6127e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 613185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void startScan(BluetoothAdapter adapter) { 614826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int mask = BluetoothReceiver.DISCOVERY_STARTED_FLAG; 615185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 616185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (!adapter.isEnabled()) { 617185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe fail("startScan() bluetooth not enabled"); 618185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 619185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 620185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (adapter.isDiscovering()) { 621185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe return; 622185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 623185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 624826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe BluetoothReceiver receiver = getBluetoothReceiver(mask); 625826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 626826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long start = System.currentTimeMillis(); 627185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe assertTrue(adapter.startDiscovery()); 628185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 629207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe while (System.currentTimeMillis() - start < START_STOP_SCAN_TIMEOUT) { 630826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (adapter.isDiscovering() && ((receiver.getFiredFlags() & mask) == mask)) { 631185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe writeOutput(String.format("startScan() completed in %d ms", 632826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe (receiver.getCompletedTime() - start))); 633826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 634185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe return; 635185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 636185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe sleep(POLL_TIME); 637185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 638185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 639826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int firedFlags = receiver.getFiredFlags(); 640826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 641185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe fail(String.format("startScan() timeout: isDiscovering=%b, flags=0x%x (expected 0x%x)", 642185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe adapter.isDiscovering(), firedFlags, mask)); 643185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 644185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 6457e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 6467e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Stops a scan for remote devices and checks to make sure that the local device is not scanning 6477e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * and that the correct actions were broadcast. 6487e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 6497e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 6507e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 651185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void stopScan(BluetoothAdapter adapter) { 652826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int mask = BluetoothReceiver.DISCOVERY_FINISHED_FLAG; 653185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 654185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (!adapter.isEnabled()) { 655185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe fail("stopScan() bluetooth not enabled"); 656185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 657185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 658185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (!adapter.isDiscovering()) { 659185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe return; 660185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 661185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 662826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe BluetoothReceiver receiver = getBluetoothReceiver(mask); 663826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 664826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long start = System.currentTimeMillis(); 665efc1d16374955f04d713c770ab47d90d190afe83Albert Mojir assertTrue(adapter.cancelDiscovery()); 666185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 667207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe while (System.currentTimeMillis() - start < START_STOP_SCAN_TIMEOUT) { 668826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!adapter.isDiscovering() && ((receiver.getFiredFlags() & mask) == mask)) { 669185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe writeOutput(String.format("stopScan() completed in %d ms", 670826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe (receiver.getCompletedTime() - start))); 671826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 672185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe return; 673185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 674185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe sleep(POLL_TIME); 675185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 676185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 677826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int firedFlags = receiver.getFiredFlags(); 678826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 679185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe fail(String.format("stopScan() timeout: isDiscovering=%b, flags=0x%x (expected 0x%x)", 680185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe adapter.isDiscovering(), firedFlags, mask)); 681185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 682185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 683185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 6847e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 6857e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Enables PAN tethering on the local device and checks to make sure that tethering is enabled. 6867e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 6877e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 6887e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 6897e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe public void enablePan(BluetoothAdapter adapter) { 69074ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh if (mPan == null) mPan = (BluetoothPan) connectProxy(adapter, BluetoothProfile.PAN); 69174ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh assertNotNull(mPan); 6927e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 6937e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long start = System.currentTimeMillis(); 69474ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh mPan.setBluetoothTethering(true); 6957e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long stop = System.currentTimeMillis(); 69674ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh assertTrue(mPan.isTetheringOn()); 6977e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 6987e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe writeOutput(String.format("enablePan() completed in %d ms", (stop - start))); 6997e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 7007e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 7017e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 7027e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Disables PAN tethering on the local device and checks to make sure that tethering is 7037e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * disabled. 7047e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 7057e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 7067e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 7077e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe public void disablePan(BluetoothAdapter adapter) { 70874ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh if (mPan == null) mPan = (BluetoothPan) connectProxy(adapter, BluetoothProfile.PAN); 70974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh assertNotNull(mPan); 7107e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 7117e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long start = System.currentTimeMillis(); 71274ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh mPan.setBluetoothTethering(false); 7137e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long stop = System.currentTimeMillis(); 71474ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh assertFalse(mPan.isTetheringOn()); 7157e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 7167e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe writeOutput(String.format("disablePan() completed in %d ms", (stop - start))); 7177e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 7187e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 7197e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 7207e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Initiates a pairing with a remote device and checks to make sure that the devices are paired 7217e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * and that the correct actions were broadcast. 7227e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 7237e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 7247e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 7257e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param passkey The pairing passkey if pairing requires a passkey. Any value if not. 7267e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param pin The pairing pin if pairing requires a pin. Any value if not. 7277e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 728826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public void pair(BluetoothAdapter adapter, BluetoothDevice device, int passkey, byte[] pin) { 72923c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe pairOrAcceptPair(adapter, device, passkey, pin, true); 73023c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe } 73123c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe 7327e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 7337e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Accepts a pairing with a remote device and checks to make sure that the devices are paired 7347e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * and that the correct actions were broadcast. 7357e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 7367e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 7377e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 7387e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param passkey The pairing passkey if pairing requires a passkey. Any value if not. 7397e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param pin The pairing pin if pairing requires a pin. Any value if not. 7407e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 74123c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe public void acceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey, 74223c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe byte[] pin) { 74323c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe pairOrAcceptPair(adapter, device, passkey, pin, false); 74423c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe } 74523c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe 7467e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 7477e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Helper method used by {@link #pair(BluetoothAdapter, BluetoothDevice, int, byte[])} and 7487e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * {@link #acceptPair(BluetoothAdapter, BluetoothDevice, int, byte[])} to either pair or accept 7497e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * a pairing request. 7507e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 7517e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 7527e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 7537e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param passkey The pairing passkey if pairing requires a passkey. Any value if not. 7547e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param pin The pairing pin if pairing requires a pin. Any value if not. 7557e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param shouldPair Whether to pair or accept the pair. 7567e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 75723c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe private void pairOrAcceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey, 7587e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe byte[] pin, boolean shouldPair) { 759826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int mask = PairReceiver.STATE_BONDING_FLAG | PairReceiver.STATE_BONDED_FLAG; 760826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long start = -1; 7612b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe String methodName; 7622b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (shouldPair) { 7632b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("pair(device=%s)", device); 7642b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } else { 7652b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("acceptPair(device=%s)", device); 7662b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } 767826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 768826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!adapter.isEnabled()) { 7692b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s bluetooth not enabled", methodName)); 770826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 771826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 772826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe PairReceiver receiver = getPairReceiver(device, passkey, pin, mask); 773826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 774826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int state = device.getBondState(); 775826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (state) { 776826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_NONE: 777826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertFalse(adapter.getBondedDevices().contains(device)); 778826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe start = System.currentTimeMillis(); 7797e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (shouldPair) { 78023c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe assertTrue(device.createBond()); 78123c067692be74c4fcd50cea48f9d469ba5288213Eric Rowe } 782826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 783826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_BONDING: 784826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mask = 0; // Don't check for received intents since we might have missed them. 785826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 786826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_BONDED: 787826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertTrue(adapter.getBondedDevices().contains(device)); 788826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return; 789826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe default: 790826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 7912b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s invalid state: state=%d", methodName, state)); 792826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 793826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 794826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long s = System.currentTimeMillis(); 795207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe while (System.currentTimeMillis() - s < PAIR_UNPAIR_TIMEOUT) { 796826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe state = device.getBondState(); 797207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe if (state == BluetoothDevice.BOND_BONDED && (receiver.getFiredFlags() & mask) == mask) { 798826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertTrue(adapter.getBondedDevices().contains(device)); 799207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe long finish = receiver.getCompletedTime(); 800207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe if (start != -1 && finish != -1) { 8012b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed in %d ms", methodName, 8022b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe (finish - start))); 803207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe } else { 8042b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed", methodName)); 805826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 806207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe removeReceiver(receiver); 807207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe return; 808826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 809826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe sleep(POLL_TIME); 810826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 811826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 812826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int firedFlags = receiver.getFiredFlags(); 813826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 8142b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)", 8152b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName, state, BluetoothDevice.BOND_BONDED, firedFlags, mask)); 816826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 817826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 8187e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 8197e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Deletes a pairing with a remote device and checks to make sure that the devices are unpaired 8207e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * and that the correct actions were broadcast. 8217e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 8227e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 8237e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 8247e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 825826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe public void unpair(BluetoothAdapter adapter, BluetoothDevice device) { 826826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int mask = PairReceiver.STATE_NONE_FLAG; 827826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long start = -1; 8282b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe String methodName = String.format("unpair(device=%s)", device); 829826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 830826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!adapter.isEnabled()) { 8312b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s bluetooth not enabled", methodName)); 832826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 833826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 834826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe PairReceiver receiver = getPairReceiver(device, 0, null, mask); 835826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 836826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int state = device.getBondState(); 837826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (state) { 838826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_NONE: 839826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertFalse(adapter.getBondedDevices().contains(device)); 840826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 841826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return; 842826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_BONDING: 843826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe start = System.currentTimeMillis(); 844826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertTrue(device.removeBond()); 845826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 846826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothDevice.BOND_BONDED: 847826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertTrue(adapter.getBondedDevices().contains(device)); 848826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe start = System.currentTimeMillis(); 849826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertTrue(device.removeBond()); 850826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 851826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe default: 852826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 8532b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s invalid state: state=%d", methodName, state)); 854826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 855826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 856826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long s = System.currentTimeMillis(); 857207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe while (System.currentTimeMillis() - s < PAIR_UNPAIR_TIMEOUT) { 858207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe if (device.getBondState() == BluetoothDevice.BOND_NONE 859207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe && (receiver.getFiredFlags() & mask) == mask) { 860826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe assertFalse(adapter.getBondedDevices().contains(device)); 861207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe long finish = receiver.getCompletedTime(); 862207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe if (start != -1 && finish != -1) { 8632b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed in %d ms", methodName, 8642b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe (finish - start))); 865207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe } else { 8662b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed", methodName)); 867826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 868207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe removeReceiver(receiver); 869207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe return; 870826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 871826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 872826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 873826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int firedFlags = receiver.getFiredFlags(); 874826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 8752b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)", 8762b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName, state, BluetoothDevice.BOND_BONDED, firedFlags, mask)); 877826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 878826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 8797e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 88003800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu * Deletes all pairings of remote devices 88103800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu * @param adapter the BT adapter 88203800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu */ 88303800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu public void unpairAll(BluetoothAdapter adapter) { 88403800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu Set<BluetoothDevice> devices = adapter.getBondedDevices(); 88503800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu for (BluetoothDevice device : devices) { 88603800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu unpair(adapter, device); 88703800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu } 88803800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu } 88903800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu 89003800b8873f70223dcfcf396a3762775dfc1a8abGuang Zhu /** 8917e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Connects a profile from the local device to a remote device and checks to make sure that the 8927e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * profile is connected and that the correct actions were broadcast. 8937e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 8947e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 8957e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 8962b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe * @param profile The profile to connect. One of {@link BluetoothProfile#A2DP}, 897c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang * {@link BluetoothProfile#HEADSET}, or {@link BluetoothProfile#HID_HOST}. 8982b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe * @param methodName The method name to printed in the logs. If null, will be 8992b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe * "connectProfile(profile=<profile>, device=<device>)" 9007e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 9012b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe public void connectProfile(BluetoothAdapter adapter, BluetoothDevice device, int profile, 9022b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe String methodName) { 9032b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (methodName == null) { 9042b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("connectProfile(profile=%d, device=%s)", profile, device); 9052b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } 906826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int mask = (ConnectProfileReceiver.STATE_CONNECTING_FLAG 907826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe | ConnectProfileReceiver.STATE_CONNECTED_FLAG); 908826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long start = -1; 909826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 910826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!adapter.isEnabled()) { 9112b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s bluetooth not enabled", methodName)); 912826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 913826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 914826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!adapter.getBondedDevices().contains(device)) { 9152b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s device not paired", methodName)); 916826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 917826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 918826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe BluetoothProfile proxy = connectProxy(adapter, profile); 9192b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe assertNotNull(proxy); 920826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 921826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe ConnectProfileReceiver receiver = getConnectProfileReceiver(device, profile, mask); 922826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 923826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int state = proxy.getConnectionState(device); 924826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (state) { 925826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_CONNECTED: 926826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 927826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return; 928826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_CONNECTING: 929826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mask = 0; // Don't check for received intents since we might have missed them. 930826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 931826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_DISCONNECTED: 932826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_DISCONNECTING: 933826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe start = System.currentTimeMillis(); 934f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh if (profile == BluetoothProfile.A2DP) { 935f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh assertTrue(((BluetoothA2dp)proxy).connect(device)); 936f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh } else if (profile == BluetoothProfile.HEADSET) { 937f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh assertTrue(((BluetoothHeadset)proxy).connect(device)); 938c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang } else if (profile == BluetoothProfile.HID_HOST) { 939c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang assertTrue(((BluetoothHidHost)proxy).connect(device)); 940f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh } 941826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 942826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe default: 943826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 9442b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s invalid state: state=%d", methodName, state)); 945826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 946826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 947826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long s = System.currentTimeMillis(); 948207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) { 949826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe state = proxy.getConnectionState(device); 950207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe if (state == BluetoothProfile.STATE_CONNECTED 951207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe && (receiver.getFiredFlags() & mask) == mask) { 952207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe long finish = receiver.getCompletedTime(); 953207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe if (start != -1 && finish != -1) { 9542b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed in %d ms", methodName, 9552b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe (finish - start))); 956207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe } else { 9572b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed", methodName)); 958826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 959207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe removeReceiver(receiver); 960207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe return; 961826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 962826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe sleep(POLL_TIME); 963826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 964826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 965826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int firedFlags = receiver.getFiredFlags(); 966826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 9672b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)", 9682b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName, state, BluetoothProfile.STATE_CONNECTED, firedFlags, mask)); 969826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 970826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 9717e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 9727e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Disconnects a profile between the local device and a remote device and checks to make sure 9737e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * that the profile is disconnected and that the correct actions were broadcast. 9747e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 9757e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 9767e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 9772b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe * @param profile The profile to disconnect. One of {@link BluetoothProfile#A2DP}, 978c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang * {@link BluetoothProfile#HEADSET}, or {@link BluetoothProfile#HID_HOST}. 9792b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe * @param methodName The method name to printed in the logs. If null, will be 9802b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe * "connectProfile(profile=<profile>, device=<device>)" 9817e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 9822b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe public void disconnectProfile(BluetoothAdapter adapter, BluetoothDevice device, int profile, 9832b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe String methodName) { 9842b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (methodName == null) { 9852b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("disconnectProfile(profile=%d, device=%s)", profile, device); 9862b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } 987826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int mask = (ConnectProfileReceiver.STATE_DISCONNECTING_FLAG 988826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe | ConnectProfileReceiver.STATE_DISCONNECTED_FLAG); 989826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long start = -1; 990826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 991826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!adapter.isEnabled()) { 9922b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s bluetooth not enabled", methodName)); 993826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 994826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 995826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe if (!adapter.getBondedDevices().contains(device)) { 9962b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s device not paired", methodName)); 997826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 998826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 999826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe BluetoothProfile proxy = connectProxy(adapter, profile); 10002b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe assertNotNull(proxy); 1001826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 1002826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe ConnectProfileReceiver receiver = getConnectProfileReceiver(device, profile, mask); 1003826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 1004826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int state = proxy.getConnectionState(device); 1005826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (state) { 1006826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_CONNECTED: 1007826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_CONNECTING: 1008826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe start = System.currentTimeMillis(); 1009f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh if (profile == BluetoothProfile.A2DP) { 1010f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh assertTrue(((BluetoothA2dp)proxy).disconnect(device)); 1011f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh } else if (profile == BluetoothProfile.HEADSET) { 1012f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh assertTrue(((BluetoothHeadset)proxy).disconnect(device)); 1013c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang } else if (profile == BluetoothProfile.HID_HOST) { 1014c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang assertTrue(((BluetoothHidHost)proxy).disconnect(device)); 1015f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh } 1016826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 1017826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_DISCONNECTED: 1018826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 1019826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return; 1020826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.STATE_DISCONNECTING: 1021826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mask = 0; // Don't check for received intents since we might have missed them. 1022826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe break; 1023826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe default: 1024826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 10252b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s invalid state: state=%d", methodName, state)); 1026826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1027826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 1028826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long s = System.currentTimeMillis(); 1029207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) { 1030826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe state = proxy.getConnectionState(device); 1031207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe if (state == BluetoothProfile.STATE_DISCONNECTED 1032207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe && (receiver.getFiredFlags() & mask) == mask) { 1033207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe long finish = receiver.getCompletedTime(); 1034207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe if (start != -1 && finish != -1) { 10352b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed in %d ms", methodName, 10362b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe (finish - start))); 1037207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe } else { 10382b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed", methodName)); 1039826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1040207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe removeReceiver(receiver); 1041207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe return; 1042826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1043826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe sleep(POLL_TIME); 1044826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1045826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 1046826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int firedFlags = receiver.getFiredFlags(); 1047826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe removeReceiver(receiver); 10482b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)", 10492b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName, state, BluetoothProfile.STATE_DISCONNECTED, firedFlags, mask)); 1050826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1051826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 10527e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 10537e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Connects the PANU to a remote NAP and checks to make sure that the PANU is connected and that 10547e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * the correct actions were broadcast. 10557e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 10567e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 10577e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 10587e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 10597e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe public void connectPan(BluetoothAdapter adapter, BluetoothDevice device) { 10607e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe connectPanOrIncomingPanConnection(adapter, device, true); 10617e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 10627e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 10637e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 10647e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Checks that a remote PANU connects to the local NAP correctly and that the correct actions 10657e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * were broadcast. 10667e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 10677e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 10687e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 10697e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 10707e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe public void incomingPanConnection(BluetoothAdapter adapter, BluetoothDevice device) { 10717e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe connectPanOrIncomingPanConnection(adapter, device, false); 10727e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 10737e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 10747e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 10757e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Helper method used by {@link #connectPan(BluetoothAdapter, BluetoothDevice)} and 10767e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * {@link #incomingPanConnection(BluetoothAdapter, BluetoothDevice)} to either connect to a 10777e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * remote NAP or verify that a remote device connected to the local NAP. 10787e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 10797e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 10807e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 10817e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param connect If the method should initiate the connection (is PANU) 10827e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 10837e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe private void connectPanOrIncomingPanConnection(BluetoothAdapter adapter, BluetoothDevice device, 10847e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe boolean connect) { 10857e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long start = -1; 10867e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe int mask, role; 10877e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe String methodName; 10887e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 10897e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (connect) { 10902b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("connectPan(device=%s)", device); 10912b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe mask = (ConnectProfileReceiver.STATE_CONNECTED_FLAG | 10922b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe ConnectProfileReceiver.STATE_CONNECTING_FLAG); 10937e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe role = BluetoothPan.LOCAL_PANU_ROLE; 10947e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } else { 10952b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("incomingPanConnection(device=%s)", device); 10962b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe mask = ConnectProfileReceiver.STATE_CONNECTED_FLAG; 10977e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe role = BluetoothPan.LOCAL_NAP_ROLE; 10987e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 10997e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11007e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (!adapter.isEnabled()) { 11012b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s bluetooth not enabled", methodName)); 11027e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11037e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11047e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (!adapter.getBondedDevices().contains(device)) { 11052b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s device not paired", methodName)); 11067e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11077e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11082b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe mPan = (BluetoothPan) connectProxy(adapter, BluetoothProfile.PAN); 110974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh assertNotNull(mPan); 11107e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe ConnectPanReceiver receiver = getConnectPanReceiver(device, role, mask); 11117e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 111274ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh int state = mPan.getConnectionState(device); 11137e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe switch (state) { 11147e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe case BluetoothPan.STATE_CONNECTED: 11157e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe removeReceiver(receiver); 11167e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe return; 11177e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe case BluetoothPan.STATE_CONNECTING: 11187e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe mask = 0; // Don't check for received intents since we might have missed them. 11197e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe break; 11207e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe case BluetoothPan.STATE_DISCONNECTED: 11217e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe case BluetoothPan.STATE_DISCONNECTING: 11227e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe start = System.currentTimeMillis(); 11237e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (role == BluetoothPan.LOCAL_PANU_ROLE) { 11247e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe Log.i("BT", "connect to pan"); 112574ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh assertTrue(mPan.connect(device)); 11267e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11277e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe break; 11287e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe default: 11297e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe removeReceiver(receiver); 11302b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s invalid state: state=%d", methodName, state)); 11317e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11327e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11337e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long s = System.currentTimeMillis(); 11347e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) { 113574ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh state = mPan.getConnectionState(device); 11367e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (state == BluetoothPan.STATE_CONNECTED 11377e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe && (receiver.getFiredFlags() & mask) == mask) { 11387e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long finish = receiver.getCompletedTime(); 11397e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (start != -1 && finish != -1) { 11402b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed in %d ms", methodName, 11412b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe (finish - start))); 11427e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } else { 11432b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed", methodName)); 11447e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11457e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe removeReceiver(receiver); 11467e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe return; 11477e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11487e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe sleep(POLL_TIME); 11497e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11507e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11517e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe int firedFlags = receiver.getFiredFlags(); 11527e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe removeReceiver(receiver); 11532b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)", 11542b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName, state, BluetoothPan.STATE_CONNECTED, firedFlags, mask)); 11557e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11567e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11577e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 11587e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Disconnects the PANU from a remote NAP and checks to make sure that the PANU is disconnected 11597e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * and that the correct actions were broadcast. 11607e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 11617e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 11627e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 11637e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 11647e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe public void disconnectPan(BluetoothAdapter adapter, BluetoothDevice device) { 11657e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe disconnectFromRemoteOrVerifyConnectNap(adapter, device, true); 11667e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11677e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11687e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 11697e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Checks that a remote PANU disconnects from the local NAP correctly and that the correct 11707e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * actions were broadcast. 11717e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 11727e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 11737e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 11747e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 11757e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe public void incomingPanDisconnection(BluetoothAdapter adapter, BluetoothDevice device) { 11767e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe disconnectFromRemoteOrVerifyConnectNap(adapter, device, false); 11777e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 11787e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11797e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 11807e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Helper method used by {@link #disconnectPan(BluetoothAdapter, BluetoothDevice)} and 11817e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * {@link #incomingPanDisconnection(BluetoothAdapter, BluetoothDevice)} to either disconnect 11827e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * from a remote NAP or verify that a remote device disconnected from the local NAP. 11837e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 11847e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param adapter The BT adapter. 11857e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param device The remote device. 11867e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param disconnect Whether the method should connect or verify. 11877e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 11887e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe private void disconnectFromRemoteOrVerifyConnectNap(BluetoothAdapter adapter, 11897e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe BluetoothDevice device, boolean disconnect) { 11907e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long start = -1; 11917e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe int mask, role; 11927e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe String methodName; 11937e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 11947e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (disconnect) { 11952b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("disconnectPan(device=%s)", device); 11962b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe mask = (ConnectProfileReceiver.STATE_DISCONNECTED_FLAG | 11972b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe ConnectProfileReceiver.STATE_DISCONNECTING_FLAG); 11987e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe role = BluetoothPan.LOCAL_PANU_ROLE; 11997e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } else { 12002b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("incomingPanDisconnection(device=%s)", device); 12012b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe mask = ConnectProfileReceiver.STATE_DISCONNECTED_FLAG; 12027e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe role = BluetoothPan.LOCAL_NAP_ROLE; 12037e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12047e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 12057e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (!adapter.isEnabled()) { 12062b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s bluetooth not enabled", methodName)); 12077e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12087e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 12097e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (!adapter.getBondedDevices().contains(device)) { 12102b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s device not paired", methodName)); 12117e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12127e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 12132b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe mPan = (BluetoothPan) connectProxy(adapter, BluetoothProfile.PAN); 121474ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh assertNotNull(mPan); 12157e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe ConnectPanReceiver receiver = getConnectPanReceiver(device, role, mask); 12167e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 121774ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh int state = mPan.getConnectionState(device); 12187e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe switch (state) { 121974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh case BluetoothPan.STATE_CONNECTED: 122074ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh case BluetoothPan.STATE_CONNECTING: 12217e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe start = System.currentTimeMillis(); 12227e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (role == BluetoothPan.LOCAL_PANU_ROLE) { 122374ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh assertTrue(mPan.disconnect(device)); 12247e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12257e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe break; 122674ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh case BluetoothPan.STATE_DISCONNECTED: 12277e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe removeReceiver(receiver); 12287e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe return; 122974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh case BluetoothPan.STATE_DISCONNECTING: 12307e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe mask = 0; // Don't check for received intents since we might have missed them. 12317e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe break; 12327e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe default: 12337e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe removeReceiver(receiver); 12342b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s invalid state: state=%d", methodName, state)); 12357e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12367e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 12377e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long s = System.currentTimeMillis(); 12387e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) { 123974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh state = mPan.getConnectionState(device); 1240c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang if (state == BluetoothHidHost.STATE_DISCONNECTED 12417e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe && (receiver.getFiredFlags() & mask) == mask) { 12427e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe long finish = receiver.getCompletedTime(); 12437e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe if (start != -1 && finish != -1) { 12442b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed in %d ms", methodName, 12452b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe (finish - start))); 12467e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } else { 12472b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe writeOutput(String.format("%s completed", methodName)); 12487e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12497e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe removeReceiver(receiver); 12507e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe return; 12517e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12527e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe sleep(POLL_TIME); 12537e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12547e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 12557e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe int firedFlags = receiver.getFiredFlags(); 12567e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe removeReceiver(receiver); 12572b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)", 1258c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang methodName, state, BluetoothHidHost.STATE_DISCONNECTED, firedFlags, mask)); 12597e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 12607e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 12617e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe /** 1262835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * Opens a SCO channel using {@link android.media.AudioManager#startBluetoothSco()} and checks 1263835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * to make sure that the channel is opened and that the correct actions were broadcast. 1264835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * 1265835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * @param adapter The BT adapter. 1266835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * @param device The remote device. 1267835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe */ 1268835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe public void startSco(BluetoothAdapter adapter, BluetoothDevice device) { 1269835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe startStopSco(adapter, device, true); 1270835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1271835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1272835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe /** 1273835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * Closes a SCO channel using {@link android.media.AudioManager#stopBluetoothSco()} and checks 1274835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * to make sure that the channel is closed and that the correct actions were broadcast. 1275835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * 1276835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * @param adapter The BT adapter. 1277835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * @param device The remote device. 1278835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe */ 1279835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe public void stopSco(BluetoothAdapter adapter, BluetoothDevice device) { 1280835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe startStopSco(adapter, device, false); 1281835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1282835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe /** 1283835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * Helper method for {@link #startSco(BluetoothAdapter, BluetoothDevice)} and 1284835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * {@link #stopSco(BluetoothAdapter, BluetoothDevice)}. 1285835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * 1286835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * @param adapter The BT adapter. 1287835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * @param device The remote device. 1288835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe * @param isStart Whether the SCO channel should be opened. 1289835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe */ 1290835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe private void startStopSco(BluetoothAdapter adapter, BluetoothDevice device, boolean isStart) { 1291835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe long start = -1; 1292835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe int mask; 1293835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe String methodName; 1294835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1295835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe if (isStart) { 12962b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("startSco(device=%s)", device); 1297835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe mask = StartStopScoReceiver.STATE_CONNECTED_FLAG; 1298835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } else { 12992b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe methodName = String.format("stopSco(device=%s)", device); 1300835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe mask = StartStopScoReceiver.STATE_DISCONNECTED_FLAG; 1301835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1302835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1303835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe if (!adapter.isEnabled()) { 13042b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s bluetooth not enabled", methodName)); 1305835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1306835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1307835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe if (!adapter.getBondedDevices().contains(device)) { 13082b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s device not paired", methodName)); 1309835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1310835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1311835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 1312835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe assertNotNull(manager); 1313835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1314835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe if (!manager.isBluetoothScoAvailableOffCall()) { 13152b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s device does not support SCO", methodName)); 1316835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1317835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1318835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe boolean isScoOn = manager.isBluetoothScoOn(); 1319835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe if (isStart == isScoOn) { 1320835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe return; 1321835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1322835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1323835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe StartStopScoReceiver receiver = getStartStopScoReceiver(mask); 1324835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe start = System.currentTimeMillis(); 1325835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe if (isStart) { 1326835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe manager.startBluetoothSco(); 1327835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } else { 1328835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe manager.stopBluetoothSco(); 1329835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1330835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1331835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe long s = System.currentTimeMillis(); 1332835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe while (System.currentTimeMillis() - s < START_STOP_SCO_TIMEOUT) { 1333835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe isScoOn = manager.isBluetoothScoOn(); 13342b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (isStart == isScoOn && (receiver.getFiredFlags() & mask) == mask) { 1335835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe long finish = receiver.getCompletedTime(); 1336835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe if (start != -1 && finish != -1) { 1337835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe writeOutput(String.format("%s completed in %d ms", methodName, 1338835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe (finish - start))); 1339835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } else { 1340835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe writeOutput(String.format("%s completed", methodName)); 1341835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1342835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe removeReceiver(receiver); 1343835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe return; 1344835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1345835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe sleep(POLL_TIME); 1346835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1347835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1348835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe int firedFlags = receiver.getFiredFlags(); 1349835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe removeReceiver(receiver); 13502b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe fail(String.format("%s timeout: on=%b (expected %b), flags=0x%x (expected 0x%x)", 1351835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe methodName, isScoOn, isStart, firedFlags, mask)); 1352835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1353835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1354835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe /** 13557e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * Writes a string to the logcat and a file if a file has been specified in the constructor. 13567e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * 13577e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe * @param s The string to be written. 13587e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe */ 1359185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe public void writeOutput(String s) { 1360185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe Log.i(mTag, s); 1361185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe if (mOutputWriter == null) { 1362185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe return; 1363185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 1364185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe try { 1365185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mOutputWriter.write(s + "\n"); 1366185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe mOutputWriter.flush(); 1367185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } catch (IOException e) { 1368185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe Log.w(mTag, "Could not write to output file", e); 1369185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 1370185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 1371185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe 1372207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe private void addReceiver(BroadcastReceiver receiver, String[] actions) { 1373826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe IntentFilter filter = new IntentFilter(); 1374207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe for (String action: actions) { 1375207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe filter.addAction(action); 1376207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe } 1377826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mContext.registerReceiver(receiver, filter); 1378826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mReceivers.add(receiver); 1379207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe } 1380207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe 1381207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe private BluetoothReceiver getBluetoothReceiver(int expectedFlags) { 1382207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe String[] actions = { 1383207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe BluetoothAdapter.ACTION_DISCOVERY_FINISHED, 1384207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe BluetoothAdapter.ACTION_DISCOVERY_STARTED, 1385207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe BluetoothAdapter.ACTION_SCAN_MODE_CHANGED, 1386207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe BluetoothAdapter.ACTION_STATE_CHANGED}; 1387207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe BluetoothReceiver receiver = new BluetoothReceiver(expectedFlags); 1388207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe addReceiver(receiver, actions); 1389826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return receiver; 1390826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1391826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 1392826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private PairReceiver getPairReceiver(BluetoothDevice device, int passkey, byte[] pin, 1393826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int expectedFlags) { 1394207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe String[] actions = { 1395207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe BluetoothDevice.ACTION_PAIRING_REQUEST, 1396207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe BluetoothDevice.ACTION_BOND_STATE_CHANGED}; 1397826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe PairReceiver receiver = new PairReceiver(device, passkey, pin, expectedFlags); 1398207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe addReceiver(receiver, actions); 1399826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return receiver; 1400826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1401826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 1402826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private ConnectProfileReceiver getConnectProfileReceiver(BluetoothDevice device, int profile, 1403826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe int expectedFlags) { 1404207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe String[] actions = { 1405207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED, 14064ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED, 1407c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED}; 1408826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile, 1409826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe expectedFlags); 1410207c0a58012d5ce102760f33b5918d8b38c2af6bEric Rowe addReceiver(receiver, actions); 1411826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return receiver; 1412826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1413826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 14147e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe private ConnectPanReceiver getConnectPanReceiver(BluetoothDevice device, int role, 14157e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe int expectedFlags) { 141674ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh String[] actions = {BluetoothPan.ACTION_CONNECTION_STATE_CHANGED}; 14177e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe ConnectPanReceiver receiver = new ConnectPanReceiver(device, role, expectedFlags); 14187e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe addReceiver(receiver, actions); 14197e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe return receiver; 14207e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe } 14217e4d0c0982cb28a86bf3d45c3b316ec7eab1e017Eric Rowe 1422835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe private StartStopScoReceiver getStartStopScoReceiver(int expectedFlags) { 1423fca8e9d919443449807f87203609e53a64368f6bEric Rowe String[] actions = {AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED}; 1424835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe StartStopScoReceiver receiver = new StartStopScoReceiver(expectedFlags); 1425835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe addReceiver(receiver, actions); 1426835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe return receiver; 1427835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe } 1428835d8ee61ecddcd3fdc0aadf500d05b914ca375fEric Rowe 1429826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private void removeReceiver(BroadcastReceiver receiver) { 1430826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mContext.unregisterReceiver(receiver); 1431826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe mReceivers.remove(receiver); 1432826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1433826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 1434826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe private BluetoothProfile connectProxy(BluetoothAdapter adapter, int profile) { 14352b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe switch (profile) { 14362b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe case BluetoothProfile.A2DP: 14372b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (mA2dp != null) { 14382b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe return mA2dp; 14392b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } 14402b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe break; 14412b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe case BluetoothProfile.HEADSET: 14422b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (mHeadset != null) { 14432b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe return mHeadset; 14442b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } 14452b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe break; 1446c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang case BluetoothProfile.HID_HOST: 14472b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (mInput != null) { 14482b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe return mInput; 14492b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } 14502b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe break; 14512b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe case BluetoothProfile.PAN: 14522b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe if (mPan != null) { 14532b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe return mPan; 14542b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } 14552b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe break; 14562b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe default: 14572b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe return null; 14582b1fb45fabcb6f6e6edfd1a7a8e394928a27afe8Eric Rowe } 1459826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe adapter.getProfileProxy(mContext, mServiceListener, profile); 1460826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe long s = System.currentTimeMillis(); 1461826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe switch (profile) { 1462826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.A2DP: 14634ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh while (mA2dp == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) { 1464826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe sleep(POLL_TIME); 1465826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1466826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return mA2dp; 1467826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe case BluetoothProfile.HEADSET: 14684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh while (mHeadset == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) { 1469826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe sleep(POLL_TIME); 1470826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1471826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return mHeadset; 1472c26c76c63d933f8057f795d05624f91b811c8c71Hansong Zhang case BluetoothProfile.HID_HOST: 14734ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh while (mInput == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) { 14744ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh sleep(POLL_TIME); 14754ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 14764ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return mInput; 147774ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh case BluetoothProfile.PAN: 147874ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh while (mPan == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) { 147974ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh sleep(POLL_TIME); 148074ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh } 148174ef1199459629c5dd9f272f8cd706d82cdfeeb1Jaikumar Ganesh return mPan; 1482826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe default: 1483826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe return null; 1484826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1485826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe } 1486826af6266c79d76b81fe850b9cd3d351597e4adbEric Rowe 1487185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe private void sleep(long time) { 1488185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe try { 1489185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe Thread.sleep(time); 1490185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } catch (InterruptedException e) { 1491185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 1492185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe } 1493185a0b04c611a287cbd866d27b0ceff77f12d97bEric Rowe} 1494