Loading core/java/android/bluetooth/BluetoothDeviceProfileState.java +25 −4 Original line number Original line Diff line number Diff line Loading @@ -136,6 +136,10 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Message msg = new Message(); Message msg = new Message(); msg.what = AUTO_CONNECT_PROFILES; msg.what = AUTO_CONNECT_PROFILES; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); sendMessageDelayed(msg, AUTO_CONNECT_DELAY); } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { // This is technically not needed, but we can get stuck sometimes. // For example, if incoming A2DP fails, we are not informed by Bluez sendMessage(TRANSITION_TO_STABLE); } } } } }; }; Loading Loading @@ -175,6 +179,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); mContext.registerReceiver(mBroadcastReceiver, filter); mContext.registerReceiver(mBroadcastReceiver, filter); Loading Loading @@ -302,7 +307,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Log.e(TAG, "Error: OutgoingHandsfree state with command:" + mCommand); Log.e(TAG, "Error: OutgoingHandsfree state with command:" + mCommand); } } mStatus = processCommand(mCommand); mStatus = processCommand(mCommand); if (!mStatus) sendMessage(TRANSITION_TO_STABLE); if (!mStatus) { sendMessage(TRANSITION_TO_STABLE); mService.sendProfileStateMessage(BluetoothProfileState.HFP, BluetoothProfileState.TRANSITION_TO_STABLE); } } } @Override @Override Loading Loading @@ -393,7 +402,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Log.e(TAG, "Error: IncomingHandsfree state with command:" + mCommand); Log.e(TAG, "Error: IncomingHandsfree state with command:" + mCommand); } } mStatus = processCommand(mCommand); mStatus = processCommand(mCommand); if (!mStatus) sendMessage(TRANSITION_TO_STABLE); if (!mStatus) { sendMessage(TRANSITION_TO_STABLE); mService.sendProfileStateMessage(BluetoothProfileState.HFP, BluetoothProfileState.TRANSITION_TO_STABLE); } } } @Override @Override Loading Loading @@ -461,7 +474,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Log.e(TAG, "Error: OutgoingA2DP state with command:" + mCommand); Log.e(TAG, "Error: OutgoingA2DP state with command:" + mCommand); } } mStatus = processCommand(mCommand); mStatus = processCommand(mCommand); if (!mStatus) sendMessage(TRANSITION_TO_STABLE); if (!mStatus) { sendMessage(TRANSITION_TO_STABLE); mService.sendProfileStateMessage(BluetoothProfileState.A2DP, BluetoothProfileState.TRANSITION_TO_STABLE); } } } @Override @Override Loading Loading @@ -549,7 +566,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Log.e(TAG, "Error: IncomingA2DP state with command:" + mCommand); Log.e(TAG, "Error: IncomingA2DP state with command:" + mCommand); } } mStatus = processCommand(mCommand); mStatus = processCommand(mCommand); if (!mStatus) sendMessage(TRANSITION_TO_STABLE); if (!mStatus) { sendMessage(TRANSITION_TO_STABLE); mService.sendProfileStateMessage(BluetoothProfileState.A2DP, BluetoothProfileState.TRANSITION_TO_STABLE); } } } @Override @Override Loading core/java/android/bluetooth/BluetoothProfileState.java +9 −4 Original line number Original line Diff line number Diff line Loading @@ -43,10 +43,10 @@ public class BluetoothProfileState extends HierarchicalStateMachine { private static final boolean DBG = true; // STOPSHIP - change to false. private static final boolean DBG = true; // STOPSHIP - change to false. private static final String TAG = "BluetoothProfileState"; private static final String TAG = "BluetoothProfileState"; public static int HFP = 0; public static final int HFP = 0; public static int A2DP = 1; public static final int A2DP = 1; private static int TRANSITION_TO_STABLE = 100; static final int TRANSITION_TO_STABLE = 100; private int mProfile; private int mProfile; private BluetoothDevice mPendingDevice; private BluetoothDevice mPendingDevice; Loading @@ -57,7 +57,7 @@ public class BluetoothProfileState extends HierarchicalStateMachine { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); String action = intent.getAction(); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) { if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) { int newState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 0); int newState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 0); if (mProfile == HFP && (newState == BluetoothHeadset.STATE_CONNECTED || if (mProfile == HFP && (newState == BluetoothHeadset.STATE_CONNECTED || Loading @@ -70,6 +70,10 @@ public class BluetoothProfileState extends HierarchicalStateMachine { newState == BluetoothA2dp.STATE_DISCONNECTED)) { newState == BluetoothA2dp.STATE_DISCONNECTED)) { sendMessage(TRANSITION_TO_STABLE); sendMessage(TRANSITION_TO_STABLE); } } } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { if (device.equals(mPendingDevice)) { sendMessage(TRANSITION_TO_STABLE); } } } } } }; }; Loading @@ -84,6 +88,7 @@ public class BluetoothProfileState extends HierarchicalStateMachine { IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); context.registerReceiver(mBroadcastReceiver, filter); context.registerReceiver(mBroadcastReceiver, filter); } } Loading core/java/android/server/BluetoothEventLoop.java +8 −1 Original line number Original line Diff line number Diff line Loading @@ -512,7 +512,14 @@ class BluetoothEventLoop { authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF; authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF; if (authorized) { if (authorized) { Log.i(TAG, "Allowing incoming A2DP / AVRCP connection from " + address); Log.i(TAG, "Allowing incoming A2DP / AVRCP connection from " + address); // Some headsets try to connect AVCTP before AVDTP - against the recommendation // If AVCTP connection fails, we get stuck in IncomingA2DP state in the state // machine. We don't handle AVCTP signals currently. We only send // intents for AVDTP state changes. We need to handle both of them in // some cases. For now, just don't move to incoming state in this case. if (!BluetoothUuid.isAvrcpTarget(uuid)) { mBluetoothService.notifyIncomingA2dpConnection(address); mBluetoothService.notifyIncomingA2dpConnection(address); } } else { } else { Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address); Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address); } } Loading core/java/android/server/BluetoothService.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -2227,6 +2227,16 @@ public class BluetoothService extends IBluetooth.Stub { mA2dpService = a2dpService; mA2dpService = a2dpService; } } public void sendProfileStateMessage(int profile, int cmd) { Message msg = new Message(); msg.what = cmd; if (profile == BluetoothProfileState.HFP) { mHfpProfileState.sendMessage(msg); } else if (profile == BluetoothProfileState.A2DP) { mA2dpProfileState.sendMessage(msg); } } private static void log(String msg) { private static void log(String msg) { Log.d(TAG, msg); Log.d(TAG, msg); } } Loading Loading
core/java/android/bluetooth/BluetoothDeviceProfileState.java +25 −4 Original line number Original line Diff line number Diff line Loading @@ -136,6 +136,10 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Message msg = new Message(); Message msg = new Message(); msg.what = AUTO_CONNECT_PROFILES; msg.what = AUTO_CONNECT_PROFILES; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); sendMessageDelayed(msg, AUTO_CONNECT_DELAY); } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { // This is technically not needed, but we can get stuck sometimes. // For example, if incoming A2DP fails, we are not informed by Bluez sendMessage(TRANSITION_TO_STABLE); } } } } }; }; Loading Loading @@ -175,6 +179,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); mContext.registerReceiver(mBroadcastReceiver, filter); mContext.registerReceiver(mBroadcastReceiver, filter); Loading Loading @@ -302,7 +307,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Log.e(TAG, "Error: OutgoingHandsfree state with command:" + mCommand); Log.e(TAG, "Error: OutgoingHandsfree state with command:" + mCommand); } } mStatus = processCommand(mCommand); mStatus = processCommand(mCommand); if (!mStatus) sendMessage(TRANSITION_TO_STABLE); if (!mStatus) { sendMessage(TRANSITION_TO_STABLE); mService.sendProfileStateMessage(BluetoothProfileState.HFP, BluetoothProfileState.TRANSITION_TO_STABLE); } } } @Override @Override Loading Loading @@ -393,7 +402,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Log.e(TAG, "Error: IncomingHandsfree state with command:" + mCommand); Log.e(TAG, "Error: IncomingHandsfree state with command:" + mCommand); } } mStatus = processCommand(mCommand); mStatus = processCommand(mCommand); if (!mStatus) sendMessage(TRANSITION_TO_STABLE); if (!mStatus) { sendMessage(TRANSITION_TO_STABLE); mService.sendProfileStateMessage(BluetoothProfileState.HFP, BluetoothProfileState.TRANSITION_TO_STABLE); } } } @Override @Override Loading Loading @@ -461,7 +474,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Log.e(TAG, "Error: OutgoingA2DP state with command:" + mCommand); Log.e(TAG, "Error: OutgoingA2DP state with command:" + mCommand); } } mStatus = processCommand(mCommand); mStatus = processCommand(mCommand); if (!mStatus) sendMessage(TRANSITION_TO_STABLE); if (!mStatus) { sendMessage(TRANSITION_TO_STABLE); mService.sendProfileStateMessage(BluetoothProfileState.A2DP, BluetoothProfileState.TRANSITION_TO_STABLE); } } } @Override @Override Loading Loading @@ -549,7 +566,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine Log.e(TAG, "Error: IncomingA2DP state with command:" + mCommand); Log.e(TAG, "Error: IncomingA2DP state with command:" + mCommand); } } mStatus = processCommand(mCommand); mStatus = processCommand(mCommand); if (!mStatus) sendMessage(TRANSITION_TO_STABLE); if (!mStatus) { sendMessage(TRANSITION_TO_STABLE); mService.sendProfileStateMessage(BluetoothProfileState.A2DP, BluetoothProfileState.TRANSITION_TO_STABLE); } } } @Override @Override Loading
core/java/android/bluetooth/BluetoothProfileState.java +9 −4 Original line number Original line Diff line number Diff line Loading @@ -43,10 +43,10 @@ public class BluetoothProfileState extends HierarchicalStateMachine { private static final boolean DBG = true; // STOPSHIP - change to false. private static final boolean DBG = true; // STOPSHIP - change to false. private static final String TAG = "BluetoothProfileState"; private static final String TAG = "BluetoothProfileState"; public static int HFP = 0; public static final int HFP = 0; public static int A2DP = 1; public static final int A2DP = 1; private static int TRANSITION_TO_STABLE = 100; static final int TRANSITION_TO_STABLE = 100; private int mProfile; private int mProfile; private BluetoothDevice mPendingDevice; private BluetoothDevice mPendingDevice; Loading @@ -57,7 +57,7 @@ public class BluetoothProfileState extends HierarchicalStateMachine { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); String action = intent.getAction(); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) { if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) { int newState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 0); int newState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 0); if (mProfile == HFP && (newState == BluetoothHeadset.STATE_CONNECTED || if (mProfile == HFP && (newState == BluetoothHeadset.STATE_CONNECTED || Loading @@ -70,6 +70,10 @@ public class BluetoothProfileState extends HierarchicalStateMachine { newState == BluetoothA2dp.STATE_DISCONNECTED)) { newState == BluetoothA2dp.STATE_DISCONNECTED)) { sendMessage(TRANSITION_TO_STABLE); sendMessage(TRANSITION_TO_STABLE); } } } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { if (device.equals(mPendingDevice)) { sendMessage(TRANSITION_TO_STABLE); } } } } } }; }; Loading @@ -84,6 +88,7 @@ public class BluetoothProfileState extends HierarchicalStateMachine { IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); context.registerReceiver(mBroadcastReceiver, filter); context.registerReceiver(mBroadcastReceiver, filter); } } Loading
core/java/android/server/BluetoothEventLoop.java +8 −1 Original line number Original line Diff line number Diff line Loading @@ -512,7 +512,14 @@ class BluetoothEventLoop { authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF; authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF; if (authorized) { if (authorized) { Log.i(TAG, "Allowing incoming A2DP / AVRCP connection from " + address); Log.i(TAG, "Allowing incoming A2DP / AVRCP connection from " + address); // Some headsets try to connect AVCTP before AVDTP - against the recommendation // If AVCTP connection fails, we get stuck in IncomingA2DP state in the state // machine. We don't handle AVCTP signals currently. We only send // intents for AVDTP state changes. We need to handle both of them in // some cases. For now, just don't move to incoming state in this case. if (!BluetoothUuid.isAvrcpTarget(uuid)) { mBluetoothService.notifyIncomingA2dpConnection(address); mBluetoothService.notifyIncomingA2dpConnection(address); } } else { } else { Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address); Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address); } } Loading
core/java/android/server/BluetoothService.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -2227,6 +2227,16 @@ public class BluetoothService extends IBluetooth.Stub { mA2dpService = a2dpService; mA2dpService = a2dpService; } } public void sendProfileStateMessage(int profile, int cmd) { Message msg = new Message(); msg.what = cmd; if (profile == BluetoothProfileState.HFP) { mHfpProfileState.sendMessage(msg); } else if (profile == BluetoothProfileState.A2DP) { mA2dpProfileState.sendMessage(msg); } } private static void log(String msg) { private static void log(String msg) { Log.d(TAG, msg); Log.d(TAG, msg); } } Loading