diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/bluetooth/BluetoothDeviceProfileState.java | 89 | ||||
-rw-r--r-- | core/java/android/content/res/AssetFileDescriptor.java | 6 |
2 files changed, 90 insertions, 5 deletions
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java index 71aefbc..9be4c8f 100644 --- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java +++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java @@ -72,6 +72,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine public static final int UNPAIR = 100; public static final int AUTO_CONNECT_PROFILES = 101; public static final int TRANSITION_TO_STABLE = 102; + public static final int CONNECT_OTHER_PROFILES = 103; private static final int AUTO_CONNECT_DELAY = 6000; // 6 secs @@ -129,10 +130,6 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine sendMessage(TRANSITION_TO_STABLE); } } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { - if (!getCurrentState().equals(mBondedDevice)) { - Log.e(TAG, "State is: " + getCurrentState()); - return; - } Message msg = new Message(); msg.what = AUTO_CONNECT_PROFILES; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); @@ -274,16 +271,39 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine if (mHeadsetService.getPriority(mDevice) == BluetoothHeadset.PRIORITY_AUTO_CONNECT && !mHeadsetService.isConnected(mDevice)) { + Log.i(TAG, "Headset:Auto Connect Profiles"); mHeadsetService.connectHeadset(mDevice); } if (mA2dpService != null && mA2dpService.getSinkPriority(mDevice) == BluetoothA2dp.PRIORITY_AUTO_CONNECT && mA2dpService.getConnectedSinks().length == 0) { + Log.i(TAG, "A2dp:Auto Connect Profiles"); mA2dpService.connectSink(mDevice); } } break; + case CONNECT_OTHER_PROFILES: + if (isPhoneDocked(mDevice)) { + break; + } + if (message.arg1 == CONNECT_A2DP_OUTGOING) { + if (mA2dpService != null && + mA2dpService.getConnectedSinks().length == 0) { + Log.i(TAG, "A2dp:Connect Other Profiles"); + mA2dpService.connectSink(mDevice); + } + } else if (message.arg1 == CONNECT_HFP_OUTGOING) { + if (!mHeadsetServiceConnected) { + deferMessage(message); + } else { + if (!mHeadsetService.isConnected(mDevice)) { + Log.i(TAG, "Headset:Connect Other Profiles"); + mHeadsetService.connectHeadset(mDevice); + } + } + } + break; case TRANSITION_TO_STABLE: // ignore. break; @@ -377,6 +397,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: + case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: @@ -449,6 +470,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: + case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: @@ -541,6 +563,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: + case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: @@ -611,6 +634,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: + case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: @@ -656,6 +680,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine } else if (mHeadsetState == BluetoothHeadset.STATE_CONNECTING) { return mHeadsetService.acceptIncomingConnect(mDevice); } else if (mHeadsetState == BluetoothHeadset.STATE_DISCONNECTED) { + handleConnectionOfOtherProfiles(command); return mHeadsetService.createIncomingConnect(mDevice); } break; @@ -665,6 +690,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine } break; case CONNECT_A2DP_INCOMING: + handleConnectionOfOtherProfiles(command); // ignore, Bluez takes care return true; case DISCONNECT_HFP_OUTGOING: @@ -713,6 +739,61 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine return false; } + private void handleConnectionOfOtherProfiles(int command) { + // The white paper recommendations mentions that when there is a + // link loss, it is the responsibility of the remote device to connect. + // Many connect only 1 profile - and they connect the second profile on + // some user action (like play being pressed) and so we need this code. + // Auto Connect code only connects to the last connected device - which + // is useful in cases like when the phone reboots. But consider the + // following case: + // User is connected to the car's phone and A2DP profile. + // User comes to the desk and places the phone in the dock + // (or any speaker or music system or even another headset) and thus + // gets connected to the A2DP profile. User goes back to the car. + // Ideally the car's system is supposed to send incoming connections + // from both Handsfree and A2DP profile. But they don't. The Auto + // connect code, will not work here because we only auto connect to the + // last connected device for that profile which in this case is the dock. + // Now suppose a user is using 2 headsets simultaneously, one for the + // phone profile one for the A2DP profile. If this is the use case, we + // expect the user to use the preference to turn off the A2DP profile in + // the Settings screen for the first headset. Else, after link loss, + // there can be an incoming connection from the first headset which + // might result in the connection of the A2DP profile (if the second + // headset is slower) and thus the A2DP profile on the second headset + // will never get connected. + // + // TODO(): Handle other profiles here. + switch (command) { + case CONNECT_HFP_INCOMING: + // Connect A2DP if there is no incoming connection + // If the priority is OFF - don't auto connect. + // If the priority is AUTO_CONNECT, auto connect code takes care. + if (mA2dpService.getSinkPriority(mDevice) == BluetoothA2dp.PRIORITY_ON) { + Message msg = new Message(); + msg.what = CONNECT_OTHER_PROFILES; + msg.arg1 = CONNECT_A2DP_OUTGOING; + sendMessageDelayed(msg, AUTO_CONNECT_DELAY); + } + break; + case CONNECT_A2DP_INCOMING: + // This is again against spec. HFP incoming connections should be made + // before A2DP, so we should not hit this case. But many devices + // don't follow this. + if (mHeadsetService.getPriority(mDevice) == BluetoothHeadset.PRIORITY_ON) { + Message msg = new Message(); + msg.what = CONNECT_OTHER_PROFILES; + msg.arg1 = CONNECT_HFP_OUTGOING; + sendMessageDelayed(msg, AUTO_CONNECT_DELAY); + } + break; + default: + break; + } + + } + /*package*/ BluetoothDevice getDevice() { return mDevice; } diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java index a37e4e8..34f1f5c 100644 --- a/core/java/android/content/res/AssetFileDescriptor.java +++ b/core/java/android/content/res/AssetFileDescriptor.java @@ -130,7 +130,11 @@ public class AssetFileDescriptor implements Parcelable { * Checks whether this file descriptor is for a memory file. */ private boolean isMemoryFile() throws IOException { - return MemoryFile.isMemoryFile(mFd.getFileDescriptor()); + try { + return MemoryFile.isMemoryFile(mFd.getFileDescriptor()); + } catch (IOException e) { + return false; + } } /** |