Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +147 −44 Original line number Diff line number Diff line Loading @@ -19,15 +19,21 @@ package com.android.systemui.statusbar.policy; import static android.bluetooth.BluetoothAdapter.ERROR; import static com.android.systemui.statusbar.policy.BluetoothUtil.connectionStateToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.deviceToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.profileStateToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.profileToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidToProfile; import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidsToString; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothA2dpSink; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHeadsetClient; import android.bluetooth.BluetoothInputDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothMap; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile.ServiceListener; import android.content.BroadcastReceiver; Loading @@ -38,24 +44,37 @@ import android.os.ParcelUuid; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.SparseBooleanArray; import android.util.SparseArray; import com.android.systemui.statusbar.policy.BluetoothUtil.Profile; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Set; public class BluetoothControllerImpl implements BluetoothController { private static final String TAG = "BluetoothController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // This controls the order in which we check the states. Since a device can only have // one state on screen, but can have multiple profiles, the later states override the // value of earlier states. So if a device has a profile in CONNECTING and one in // CONNECTED, it will show as CONNECTED, theoretically this shouldn't really happen often, // but seemed worth noting. private static final int[] CONNECTION_STATES = { BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED, }; private final Context mContext; private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>(); private final BluetoothAdapter mAdapter; private final Receiver mReceiver = new Receiver(); private final ArrayMap<BluetoothDevice, DeviceInfo> mDeviceInfo = new ArrayMap<>(); private final SparseArray<BluetoothProfile> mProfiles = new SparseArray<>(); private boolean mEnabled; private boolean mConnecting; Loading @@ -73,7 +92,8 @@ public class BluetoothControllerImpl implements BluetoothController { mReceiver.register(); setAdapterState(mAdapter.getState()); updateBondedBluetoothDevices(); updateBluetoothDevices(); bindAllProfiles(); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { Loading @@ -83,6 +103,7 @@ public class BluetoothControllerImpl implements BluetoothController { pw.print(" mConnecting="); pw.println(mConnecting); pw.print(" mLastDevice="); pw.println(mLastDevice); pw.print(" mCallbacks.size="); pw.println(mCallbacks.size()); pw.print(" mProfiles="); pw.println(profilesToString(mProfiles)); pw.print(" mDeviceInfo.size="); pw.println(mDeviceInfo.size()); for (int i = 0; i < mDeviceInfo.size(); i++) { final BluetoothDevice device = mDeviceInfo.keyAt(i); Loading @@ -95,7 +116,22 @@ public class BluetoothControllerImpl implements BluetoothController { private static String infoToString(DeviceInfo info) { return info == null ? null : ("connectionState=" + connectionStateToString(info.connectionState) + ",bonded=" + info.bonded); connectionStateToString(info.connectionState) + ",bonded=" + info.bonded + ",profiles=" + profilesToString(info.connectedProfiles)); } private static String profilesToString(SparseArray<?> profiles) { final int N = profiles.size(); final StringBuffer buffer = new StringBuffer(); buffer.append('['); for (int i = 0; i < N; i++) { if (i != 0) { buffer.append(','); } buffer.append(BluetoothUtil.profileToString(profiles.keyAt(i))); } buffer.append(']'); return buffer.toString(); } public void addStateChangedCallback(Callback cb) { Loading Loading @@ -178,6 +214,7 @@ public class BluetoothControllerImpl implements BluetoothController { private void connect(PairedDevice pd, final boolean connect) { if (mAdapter == null || pd == null || pd.tag == null) return; final BluetoothDevice device = (BluetoothDevice) pd.tag; final DeviceInfo info = mDeviceInfo.get(device); final String action = connect ? "connect" : "disconnect"; if (DEBUG) Log.d(TAG, action + " " + deviceToString(device)); final ParcelUuid[] uuids = device.getUuids(); Loading @@ -185,7 +222,9 @@ public class BluetoothControllerImpl implements BluetoothController { Log.w(TAG, "No uuids returned, aborting " + action + " for " + deviceToString(device)); return; } final SparseBooleanArray profiles = new SparseBooleanArray(); SparseArray<Boolean> profiles = new SparseArray<>(); if (connect) { // When connecting add every profile we can recognize by uuid. for (ParcelUuid uuid : uuids) { final int profile = uuidToProfile(uuid); if (profile == 0) { Loading @@ -193,36 +232,26 @@ public class BluetoothControllerImpl implements BluetoothController { + uuidToString(uuid)); continue; } final int profileState = mAdapter.getProfileConnectionState(profile); if (DEBUG && !profiles.get(profile)) Log.d(TAG, "Profile " + profileToString(profile) + " state = " + profileStateToString(profileState)); final boolean connected = profileState == BluetoothProfile.STATE_CONNECTED; if (connect != connected) { final boolean connected = info.connectedProfiles.get(profile, false); if (!connected) { profiles.put(profile, true); } } } else { // When disconnecting, just add every profile we know they are connected to. profiles = info.connectedProfiles; } for (int i = 0; i < profiles.size(); i++) { final int profile = profiles.keyAt(i); mAdapter.getProfileProxy(mContext, new ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { if (DEBUG) Log.d(TAG, "onServiceConnected " + profileToString(profile)); final Profile p = BluetoothUtil.getProfile(proxy); if (p == null) { Log.w(TAG, "Unable get get Profile for " + profileToString(profile)); } else { if (mProfiles.indexOfKey(profile) >= 0) { final Profile p = BluetoothUtil.getProfile(mProfiles.get(profile)); final boolean ok = connect ? p.connect(device) : p.disconnect(device); if (DEBUG) Log.d(TAG, action + " " + profileToString(profile) + " " + (ok ? "succeeded" : "failed")); } else { Log.w(TAG, "Unable get get Profile for " + profileToString(profile)); } } @Override public void onServiceDisconnected(int profile) { if (DEBUG) Log.d(TAG, "onServiceDisconnected " + profileToString(profile)); } }, profile); } } @Override Loading @@ -230,11 +259,13 @@ public class BluetoothControllerImpl implements BluetoothController { return mLastDevice != null ? mLastDevice.getAliasName() : null; } private void updateBondedBluetoothDevices() { private void updateBluetoothDevices() { if (mAdapter == null) return; final Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices(); for (DeviceInfo info : mDeviceInfo.values()) { info.bonded = false; info.connectionState = ERROR; info.connectedProfiles.clear(); } int bondedCount = 0; BluetoothDevice lastBonded = null; Loading @@ -248,12 +279,62 @@ public class BluetoothControllerImpl implements BluetoothController { } } } final int N = mProfiles.size(); final int[] connectionType = new int[1]; for (int i = 0; i < CONNECTION_STATES.length; i++) { connectionType[0] = CONNECTION_STATES[i]; for (int j = 0; j < N; j++) { int profile = mProfiles.keyAt(j); List<BluetoothDevice> devices = mProfiles.get(profile) .getDevicesMatchingConnectionStates(connectionType); for (int k = 0; k < devices.size(); k++) { DeviceInfo info = mDeviceInfo.get(devices.get(k)); info.connectionState = CONNECTION_STATES[i]; if (CONNECTION_STATES[i] == BluetoothProfile.STATE_CONNECTED) { info.connectedProfiles.put(profile, true); } } } } if (mLastDevice == null && bondedCount == 1) { mLastDevice = lastBonded; } // If we are no longer connected to the current device, see if we are connected to // something else, so we don't display a name we aren't connected to. if (mLastDevice != null && mDeviceInfo.get(mLastDevice).connectionState != BluetoothProfile.STATE_CONNECTED) { // Make sure we don't keep this device while it isn't connected. mLastDevice = null; // Look for anything else connected. final int size = mDeviceInfo.size(); for (int i = 0; i < size; i++) { BluetoothDevice device = mDeviceInfo.keyAt(i); DeviceInfo info = mDeviceInfo.valueAt(i); if (info.connectionState == BluetoothProfile.STATE_CONNECTED) { mLastDevice = device; break; } } } firePairedDevicesChanged(); } private void bindAllProfiles() { // Note: This needs to contain all of the types that can be returned by BluetoothUtil // otherwise we can't find the profiles we need when we connect/disconnect. mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP_SINK); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.AVRCP_CONTROLLER); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET_CLIENT); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.INPUT_DEVICE); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.MAP); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.PAN); // Note Health is not in this list because health devices aren't 'connected'. // If profiles are expanded to use more than just connection state and connect/disconnect // then it should be added. } private void firePairedDevicesChanged() { for (Callback cb : mCallbacks) { cb.onBluetoothPairedDevicesChanged(); Loading Loading @@ -283,6 +364,20 @@ public class BluetoothControllerImpl implements BluetoothController { cb.onBluetoothStateChange(mEnabled, mConnecting); } private final ServiceListener mProfileListener = new ServiceListener() { @Override public void onServiceDisconnected(int profile) { mProfiles.remove(profile); updateBluetoothDevices(); } @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { mProfiles.put(profile, proxy); updateBluetoothDevices(); } }; private final class Receiver extends BroadcastReceiver { public void register() { final IntentFilter filter = new IntentFilter(); Loading @@ -290,6 +385,15 @@ public class BluetoothControllerImpl implements BluetoothController { filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ALIAS_CHANGED); filter.addAction(BluetoothDevice.ACTION_CLASS_CHANGED); filter.addAction(BluetoothDevice.ACTION_UUID); filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothMap.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED); mContext.registerReceiver(this, filter); } Loading @@ -301,16 +405,13 @@ public class BluetoothControllerImpl implements BluetoothController { setAdapterState(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, ERROR)); if (DEBUG) Log.d(TAG, "ACTION_STATE_CHANGED " + mEnabled); } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { final DeviceInfo info = updateInfo(device); updateInfo(device); final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, ERROR); if (state != ERROR) { info.connectionState = state; } mLastDevice = device; if (DEBUG) Log.d(TAG, "ACTION_CONNECTION_STATE_CHANGED " + connectionStateToString(state) + " " + deviceToString(device)); setConnecting(info.connectionState == BluetoothAdapter.STATE_CONNECTING); setConnecting(state == BluetoothAdapter.STATE_CONNECTING); } else if (action.equals(BluetoothDevice.ACTION_ALIAS_CHANGED)) { updateInfo(device); mLastDevice = device; Loading @@ -318,7 +419,8 @@ public class BluetoothControllerImpl implements BluetoothController { if (DEBUG) Log.d(TAG, "ACTION_BOND_STATE_CHANGED " + device); // we'll update all bonded devices below } updateBondedBluetoothDevices(); // Always update bluetooth devices state. updateBluetoothDevices(); } } Loading @@ -332,5 +434,6 @@ public class BluetoothControllerImpl implements BluetoothController { private static class DeviceInfo { int connectionState = BluetoothAdapter.STATE_DISCONNECTED; boolean bonded; // per getBondedDevices SparseArray<Boolean> connectedProfiles = new SparseArray<>(); } } packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java +9 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,10 @@ public class BluetoothUtil { if (profile == BluetoothProfile.HEADSET) return "HEADSET"; if (profile == BluetoothProfile.A2DP) return "A2DP"; if (profile == BluetoothProfile.AVRCP_CONTROLLER) return "AVRCP_CONTROLLER"; return "UNKNOWN"; if (profile == BluetoothProfile.PAN) return "PAN"; if (profile == BluetoothProfile.INPUT_DEVICE) return "INPUT_DEVICE"; if (profile == BluetoothProfile.MAP) return "MAP"; return "UNKNOWN(" + profile + ")"; } public static String profileStateToString(int state) { Loading Loading @@ -106,6 +109,11 @@ public class BluetoothUtil { if (BluetoothUuid.AvrcpController.equals(uuid)) return BluetoothProfile.AVRCP_CONTROLLER; if (BluetoothUuid.Hid.equals(uuid)) return BluetoothProfile.INPUT_DEVICE; if (BluetoothUuid.Hogp.equals(uuid)) return BluetoothProfile.INPUT_DEVICE; if (BluetoothUuid.NAP.equals(uuid)) return BluetoothProfile.PAN; return 0; } Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +147 −44 Original line number Diff line number Diff line Loading @@ -19,15 +19,21 @@ package com.android.systemui.statusbar.policy; import static android.bluetooth.BluetoothAdapter.ERROR; import static com.android.systemui.statusbar.policy.BluetoothUtil.connectionStateToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.deviceToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.profileStateToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.profileToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidToProfile; import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidToString; import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidsToString; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothA2dpSink; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHeadsetClient; import android.bluetooth.BluetoothInputDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothMap; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile.ServiceListener; import android.content.BroadcastReceiver; Loading @@ -38,24 +44,37 @@ import android.os.ParcelUuid; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.SparseBooleanArray; import android.util.SparseArray; import com.android.systemui.statusbar.policy.BluetoothUtil.Profile; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Set; public class BluetoothControllerImpl implements BluetoothController { private static final String TAG = "BluetoothController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // This controls the order in which we check the states. Since a device can only have // one state on screen, but can have multiple profiles, the later states override the // value of earlier states. So if a device has a profile in CONNECTING and one in // CONNECTED, it will show as CONNECTED, theoretically this shouldn't really happen often, // but seemed worth noting. private static final int[] CONNECTION_STATES = { BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED, }; private final Context mContext; private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>(); private final BluetoothAdapter mAdapter; private final Receiver mReceiver = new Receiver(); private final ArrayMap<BluetoothDevice, DeviceInfo> mDeviceInfo = new ArrayMap<>(); private final SparseArray<BluetoothProfile> mProfiles = new SparseArray<>(); private boolean mEnabled; private boolean mConnecting; Loading @@ -73,7 +92,8 @@ public class BluetoothControllerImpl implements BluetoothController { mReceiver.register(); setAdapterState(mAdapter.getState()); updateBondedBluetoothDevices(); updateBluetoothDevices(); bindAllProfiles(); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { Loading @@ -83,6 +103,7 @@ public class BluetoothControllerImpl implements BluetoothController { pw.print(" mConnecting="); pw.println(mConnecting); pw.print(" mLastDevice="); pw.println(mLastDevice); pw.print(" mCallbacks.size="); pw.println(mCallbacks.size()); pw.print(" mProfiles="); pw.println(profilesToString(mProfiles)); pw.print(" mDeviceInfo.size="); pw.println(mDeviceInfo.size()); for (int i = 0; i < mDeviceInfo.size(); i++) { final BluetoothDevice device = mDeviceInfo.keyAt(i); Loading @@ -95,7 +116,22 @@ public class BluetoothControllerImpl implements BluetoothController { private static String infoToString(DeviceInfo info) { return info == null ? null : ("connectionState=" + connectionStateToString(info.connectionState) + ",bonded=" + info.bonded); connectionStateToString(info.connectionState) + ",bonded=" + info.bonded + ",profiles=" + profilesToString(info.connectedProfiles)); } private static String profilesToString(SparseArray<?> profiles) { final int N = profiles.size(); final StringBuffer buffer = new StringBuffer(); buffer.append('['); for (int i = 0; i < N; i++) { if (i != 0) { buffer.append(','); } buffer.append(BluetoothUtil.profileToString(profiles.keyAt(i))); } buffer.append(']'); return buffer.toString(); } public void addStateChangedCallback(Callback cb) { Loading Loading @@ -178,6 +214,7 @@ public class BluetoothControllerImpl implements BluetoothController { private void connect(PairedDevice pd, final boolean connect) { if (mAdapter == null || pd == null || pd.tag == null) return; final BluetoothDevice device = (BluetoothDevice) pd.tag; final DeviceInfo info = mDeviceInfo.get(device); final String action = connect ? "connect" : "disconnect"; if (DEBUG) Log.d(TAG, action + " " + deviceToString(device)); final ParcelUuid[] uuids = device.getUuids(); Loading @@ -185,7 +222,9 @@ public class BluetoothControllerImpl implements BluetoothController { Log.w(TAG, "No uuids returned, aborting " + action + " for " + deviceToString(device)); return; } final SparseBooleanArray profiles = new SparseBooleanArray(); SparseArray<Boolean> profiles = new SparseArray<>(); if (connect) { // When connecting add every profile we can recognize by uuid. for (ParcelUuid uuid : uuids) { final int profile = uuidToProfile(uuid); if (profile == 0) { Loading @@ -193,36 +232,26 @@ public class BluetoothControllerImpl implements BluetoothController { + uuidToString(uuid)); continue; } final int profileState = mAdapter.getProfileConnectionState(profile); if (DEBUG && !profiles.get(profile)) Log.d(TAG, "Profile " + profileToString(profile) + " state = " + profileStateToString(profileState)); final boolean connected = profileState == BluetoothProfile.STATE_CONNECTED; if (connect != connected) { final boolean connected = info.connectedProfiles.get(profile, false); if (!connected) { profiles.put(profile, true); } } } else { // When disconnecting, just add every profile we know they are connected to. profiles = info.connectedProfiles; } for (int i = 0; i < profiles.size(); i++) { final int profile = profiles.keyAt(i); mAdapter.getProfileProxy(mContext, new ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { if (DEBUG) Log.d(TAG, "onServiceConnected " + profileToString(profile)); final Profile p = BluetoothUtil.getProfile(proxy); if (p == null) { Log.w(TAG, "Unable get get Profile for " + profileToString(profile)); } else { if (mProfiles.indexOfKey(profile) >= 0) { final Profile p = BluetoothUtil.getProfile(mProfiles.get(profile)); final boolean ok = connect ? p.connect(device) : p.disconnect(device); if (DEBUG) Log.d(TAG, action + " " + profileToString(profile) + " " + (ok ? "succeeded" : "failed")); } else { Log.w(TAG, "Unable get get Profile for " + profileToString(profile)); } } @Override public void onServiceDisconnected(int profile) { if (DEBUG) Log.d(TAG, "onServiceDisconnected " + profileToString(profile)); } }, profile); } } @Override Loading @@ -230,11 +259,13 @@ public class BluetoothControllerImpl implements BluetoothController { return mLastDevice != null ? mLastDevice.getAliasName() : null; } private void updateBondedBluetoothDevices() { private void updateBluetoothDevices() { if (mAdapter == null) return; final Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices(); for (DeviceInfo info : mDeviceInfo.values()) { info.bonded = false; info.connectionState = ERROR; info.connectedProfiles.clear(); } int bondedCount = 0; BluetoothDevice lastBonded = null; Loading @@ -248,12 +279,62 @@ public class BluetoothControllerImpl implements BluetoothController { } } } final int N = mProfiles.size(); final int[] connectionType = new int[1]; for (int i = 0; i < CONNECTION_STATES.length; i++) { connectionType[0] = CONNECTION_STATES[i]; for (int j = 0; j < N; j++) { int profile = mProfiles.keyAt(j); List<BluetoothDevice> devices = mProfiles.get(profile) .getDevicesMatchingConnectionStates(connectionType); for (int k = 0; k < devices.size(); k++) { DeviceInfo info = mDeviceInfo.get(devices.get(k)); info.connectionState = CONNECTION_STATES[i]; if (CONNECTION_STATES[i] == BluetoothProfile.STATE_CONNECTED) { info.connectedProfiles.put(profile, true); } } } } if (mLastDevice == null && bondedCount == 1) { mLastDevice = lastBonded; } // If we are no longer connected to the current device, see if we are connected to // something else, so we don't display a name we aren't connected to. if (mLastDevice != null && mDeviceInfo.get(mLastDevice).connectionState != BluetoothProfile.STATE_CONNECTED) { // Make sure we don't keep this device while it isn't connected. mLastDevice = null; // Look for anything else connected. final int size = mDeviceInfo.size(); for (int i = 0; i < size; i++) { BluetoothDevice device = mDeviceInfo.keyAt(i); DeviceInfo info = mDeviceInfo.valueAt(i); if (info.connectionState == BluetoothProfile.STATE_CONNECTED) { mLastDevice = device; break; } } } firePairedDevicesChanged(); } private void bindAllProfiles() { // Note: This needs to contain all of the types that can be returned by BluetoothUtil // otherwise we can't find the profiles we need when we connect/disconnect. mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP_SINK); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.AVRCP_CONTROLLER); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET_CLIENT); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.INPUT_DEVICE); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.MAP); mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.PAN); // Note Health is not in this list because health devices aren't 'connected'. // If profiles are expanded to use more than just connection state and connect/disconnect // then it should be added. } private void firePairedDevicesChanged() { for (Callback cb : mCallbacks) { cb.onBluetoothPairedDevicesChanged(); Loading Loading @@ -283,6 +364,20 @@ public class BluetoothControllerImpl implements BluetoothController { cb.onBluetoothStateChange(mEnabled, mConnecting); } private final ServiceListener mProfileListener = new ServiceListener() { @Override public void onServiceDisconnected(int profile) { mProfiles.remove(profile); updateBluetoothDevices(); } @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { mProfiles.put(profile, proxy); updateBluetoothDevices(); } }; private final class Receiver extends BroadcastReceiver { public void register() { final IntentFilter filter = new IntentFilter(); Loading @@ -290,6 +385,15 @@ public class BluetoothControllerImpl implements BluetoothController { filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ALIAS_CHANGED); filter.addAction(BluetoothDevice.ACTION_CLASS_CHANGED); filter.addAction(BluetoothDevice.ACTION_UUID); filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothMap.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED); mContext.registerReceiver(this, filter); } Loading @@ -301,16 +405,13 @@ public class BluetoothControllerImpl implements BluetoothController { setAdapterState(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, ERROR)); if (DEBUG) Log.d(TAG, "ACTION_STATE_CHANGED " + mEnabled); } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { final DeviceInfo info = updateInfo(device); updateInfo(device); final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, ERROR); if (state != ERROR) { info.connectionState = state; } mLastDevice = device; if (DEBUG) Log.d(TAG, "ACTION_CONNECTION_STATE_CHANGED " + connectionStateToString(state) + " " + deviceToString(device)); setConnecting(info.connectionState == BluetoothAdapter.STATE_CONNECTING); setConnecting(state == BluetoothAdapter.STATE_CONNECTING); } else if (action.equals(BluetoothDevice.ACTION_ALIAS_CHANGED)) { updateInfo(device); mLastDevice = device; Loading @@ -318,7 +419,8 @@ public class BluetoothControllerImpl implements BluetoothController { if (DEBUG) Log.d(TAG, "ACTION_BOND_STATE_CHANGED " + device); // we'll update all bonded devices below } updateBondedBluetoothDevices(); // Always update bluetooth devices state. updateBluetoothDevices(); } } Loading @@ -332,5 +434,6 @@ public class BluetoothControllerImpl implements BluetoothController { private static class DeviceInfo { int connectionState = BluetoothAdapter.STATE_DISCONNECTED; boolean bonded; // per getBondedDevices SparseArray<Boolean> connectedProfiles = new SparseArray<>(); } }
packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java +9 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,10 @@ public class BluetoothUtil { if (profile == BluetoothProfile.HEADSET) return "HEADSET"; if (profile == BluetoothProfile.A2DP) return "A2DP"; if (profile == BluetoothProfile.AVRCP_CONTROLLER) return "AVRCP_CONTROLLER"; return "UNKNOWN"; if (profile == BluetoothProfile.PAN) return "PAN"; if (profile == BluetoothProfile.INPUT_DEVICE) return "INPUT_DEVICE"; if (profile == BluetoothProfile.MAP) return "MAP"; return "UNKNOWN(" + profile + ")"; } public static String profileStateToString(int state) { Loading Loading @@ -106,6 +109,11 @@ public class BluetoothUtil { if (BluetoothUuid.AvrcpController.equals(uuid)) return BluetoothProfile.AVRCP_CONTROLLER; if (BluetoothUuid.Hid.equals(uuid)) return BluetoothProfile.INPUT_DEVICE; if (BluetoothUuid.Hogp.equals(uuid)) return BluetoothProfile.INPUT_DEVICE; if (BluetoothUuid.NAP.equals(uuid)) return BluetoothProfile.PAN; return 0; } Loading