diff options
author | Jason Monk <jmonk@google.com> | 2015-02-04 13:00:55 -0500 |
---|---|---|
committer | Jason Monk <jmonk@google.com> | 2015-03-02 10:40:21 -0500 |
commit | be3c5dbee66758517a8198f98ed2e20c80af326b (patch) | |
tree | 24cf7c862730a2f530710e9aaae33f52d932ee64 /packages/SystemUI | |
parent | c94ea96cb77b27d93e675912b2420bd43ae9b8fe (diff) | |
download | frameworks_base-be3c5dbee66758517a8198f98ed2e20c80af326b.zip frameworks_base-be3c5dbee66758517a8198f98ed2e20c80af326b.tar.gz frameworks_base-be3c5dbee66758517a8198f98ed2e20c80af326b.tar.bz2 |
Make QS use SettingsLib's BT code
A couple of changes needed to be made to SettingsLib to support this.
- SettingsLib needed to track ACTION_CONNECTION_STATE_CHANGED
- The summary code needed to move from Settings up into SettingsLib
- Added a getMaxConnectionState to CachedBluetoothDevice
- This simplifies the states of all of the profiles into
one.
Change-Id: I7f828f0038ad0cf39274986ece6d486d545f0286
Diffstat (limited to 'packages/SystemUI')
5 files changed, 120 insertions, 721 deletions
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 035bb0e..0b3ba2e 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -47,6 +47,7 @@ <!-- Networking and telephony --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index c15566f..b42b5f6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -16,6 +16,8 @@ package com.android.systemui.qs.tiles; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; import android.provider.Settings; @@ -23,13 +25,14 @@ import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.systemui.R; import com.android.systemui.qs.QSDetailItems; import com.android.systemui.qs.QSDetailItems.Item; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.BluetoothController; -import com.android.systemui.statusbar.policy.BluetoothController.PairedDevice; +import java.util.Collection; import java.util.Set; /** Quick settings tile: Bluetooth **/ @@ -143,7 +146,7 @@ public class BluetoothTile extends QSTile<QSTile.BooleanState> { refreshState(); } @Override - public void onBluetoothPairedDevicesChanged() { + public void onBluetoothDevicesChanged() { mUiHandler.post(new Runnable() { @Override public void run() { @@ -199,19 +202,21 @@ public class BluetoothTile extends QSTile<QSTile.BooleanState> { private void updateItems() { if (mItems == null) return; Item[] items = null; - final Set<PairedDevice> devices = mController.getPairedDevices(); + final Collection<CachedBluetoothDevice> devices = mController.getDevices(); if (devices != null) { - items = new Item[devices.size()]; + items = new Item[getBondedCount(devices)]; int i = 0; - for (PairedDevice device : devices) { + for (CachedBluetoothDevice device : devices) { + if (device.getBondState() == BluetoothDevice.BOND_NONE) continue; final Item item = new Item(); item.icon = R.drawable.ic_qs_bluetooth_on; - item.line1 = device.name; - if (device.state == PairedDevice.STATE_CONNECTED) { + item.line1 = device.getName(); + int state = device.getMaxConnectionState(); + if (state == BluetoothProfile.STATE_CONNECTED) { item.icon = R.drawable.ic_qs_bluetooth_connected; item.line2 = mContext.getString(R.string.quick_settings_connected); item.canDisconnect = true; - } else if (device.state == PairedDevice.STATE_CONNECTING) { + } else if (state == BluetoothProfile.STATE_CONNECTING) { item.icon = R.drawable.ic_qs_bluetooth_connecting; item.line2 = mContext.getString(R.string.quick_settings_connecting); } @@ -222,11 +227,22 @@ public class BluetoothTile extends QSTile<QSTile.BooleanState> { mItems.setItems(items); } + private int getBondedCount(Collection<CachedBluetoothDevice> devices) { + int ct = 0; + for (CachedBluetoothDevice device : devices) { + if (device.getBondState() != BluetoothDevice.BOND_NONE) { + ct++; + } + } + return ct; + } + @Override public void onDetailItemClick(Item item) { if (item == null || item.tag == null) return; - final PairedDevice device = (PairedDevice) item.tag; - if (device != null && device.state == PairedDevice.STATE_DISCONNECTED) { + final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag; + if (device != null && device.getMaxConnectionState() + == BluetoothProfile.STATE_DISCONNECTED) { mController.connect(device); } } @@ -234,7 +250,7 @@ public class BluetoothTile extends QSTile<QSTile.BooleanState> { @Override public void onDetailItemDisconnect(Item item) { if (item == null || item.tag == null) return; - final PairedDevice device = (PairedDevice) item.tag; + final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag; if (device != null) { mController.disconnect(device); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java index cbdd138..cbe4c4d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java @@ -16,7 +16,9 @@ package com.android.systemui.statusbar.policy; -import java.util.Set; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; + +import java.util.Collection; public interface BluetoothController { void addStateChangedCallback(Callback callback); @@ -28,32 +30,12 @@ public interface BluetoothController { boolean isBluetoothConnecting(); String getLastDeviceName(); void setBluetoothEnabled(boolean enabled); - Set<PairedDevice> getPairedDevices(); - void connect(PairedDevice device); - void disconnect(PairedDevice device); + Collection<CachedBluetoothDevice> getDevices(); + void connect(CachedBluetoothDevice device); + void disconnect(CachedBluetoothDevice device); public interface Callback { void onBluetoothStateChange(boolean enabled, boolean connecting); - void onBluetoothPairedDevicesChanged(); - } - - public static final class PairedDevice { - public static int STATE_DISCONNECTED = 0; - public static int STATE_CONNECTING = 1; - public static int STATE_CONNECTED = 2; - public static int STATE_DISCONNECTING = 3; - - public String id; - public String name; - public int state = STATE_DISCONNECTED; - public Object tag; - - public static String stateToString(int state) { - if (state == STATE_DISCONNECTED) return "STATE_DISCONNECTED"; - if (state == STATE_CONNECTING) return "STATE_CONNECTING"; - if (state == STATE_CONNECTED) return "STATE_CONNECTED"; - if (state == STATE_DISCONNECTING) return "STATE_DISCONNECTING"; - return "UNKNOWN"; - } + void onBluetoothDevicesChanged(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java index 81e1e45..8d4f302 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java @@ -16,138 +16,57 @@ 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.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; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; import android.os.Looper; -import android.os.Message; -import android.os.ParcelUuid; -import android.util.ArrayMap; -import android.util.ArraySet; import android.util.Log; -import android.util.SparseArray; -import com.android.systemui.statusbar.policy.BluetoothUtil.Profile; +import com.android.settingslib.bluetooth.BluetoothCallback; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.LocalBluetoothManager; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Set; +import java.util.Collection; -public class BluetoothControllerImpl implements BluetoothController { +public class BluetoothControllerImpl implements BluetoothController, BluetoothCallback, + CachedBluetoothDevice.Callback { 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, - }; - // Update all the BT device states. - private static final int MSG_UPDATE_CONNECTION_STATES = 1; - // Update just one BT device. - private static final int MSG_UPDATE_SINGLE_CONNECTION_STATE = 2; - // Update whether devices are bonded or not. - private static final int MSG_UPDATE_BONDED_DEVICES = 3; - - private static final int MSG_ADD_PROFILE = 4; - private static final int MSG_REM_PROFILE = 5; - - 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 final H mHandler; + private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>(); + private final LocalBluetoothManager mLocalBluetoothManager; private boolean mEnabled; private boolean mConnecting; - private BluetoothDevice mLastDevice; + private CachedBluetoothDevice mLastDevice; public BluetoothControllerImpl(Context context, Looper bgLooper) { - mContext = context; - mHandler = new H(bgLooper); - - final BluetoothManager bluetoothManager = - (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); - mAdapter = bluetoothManager.getAdapter(); - if (mAdapter == null) { - Log.w(TAG, "Default BT adapter not found"); - return; + mLocalBluetoothManager = LocalBluetoothManager.getInstance(context, null); + if (mLocalBluetoothManager != null) { + mLocalBluetoothManager.getEventManager().registerCallback(this); + onBluetoothStateChanged( + mLocalBluetoothManager.getBluetoothAdapter().getBluetoothState()); } - - mReceiver.register(); - setAdapterState(mAdapter.getState()); - updateBondedDevices(); - bindAllProfiles(); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("BluetoothController state:"); - pw.print(" mAdapter="); pw.println(mAdapter); + pw.print(" mLocalBluetoothManager="); pw.println(mLocalBluetoothManager); pw.print(" mEnabled="); pw.println(mEnabled); 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); - final DeviceInfo info = mDeviceInfo.valueAt(i); - pw.print(" "); pw.print(deviceToString(device)); - pw.print('('); pw.print(uuidsToString(device)); pw.print(')'); - pw.print(" "); pw.println(infoToString(info)); + pw.println(" Bluetooth Devices:"); + for (CachedBluetoothDevice device : + mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()) { + pw.println(" " + getDeviceString(device)); } } - private static String infoToString(DeviceInfo info) { - return info == null ? null : ("connectionState=" + - connectionStateToString(CONNECTION_STATES[info.connectionStateIndex]) - + ",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(); + private String getDeviceString(CachedBluetoothDevice device) { + return device.getName() + " " + device.getBondState() + " " + device.isConnected(); } public void addStateChangedCallback(Callback cb) { @@ -162,411 +81,126 @@ public class BluetoothControllerImpl implements BluetoothController { @Override public boolean isBluetoothEnabled() { - return mAdapter != null && mAdapter.isEnabled(); + return mEnabled; } @Override public boolean isBluetoothConnected() { - return mAdapter != null - && mAdapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED; + return mLocalBluetoothManager != null + && mLocalBluetoothManager.getBluetoothAdapter().getConnectionState() + == BluetoothAdapter.STATE_CONNECTED; } @Override public boolean isBluetoothConnecting() { - return mAdapter != null - && mAdapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTING; + return mConnecting; } @Override public void setBluetoothEnabled(boolean enabled) { - if (mAdapter != null) { - if (enabled) { - mAdapter.enable(); - } else { - mAdapter.disable(); - } + if (mLocalBluetoothManager != null) { + mLocalBluetoothManager.getBluetoothAdapter().setBluetoothEnabled(enabled); } } @Override public boolean isBluetoothSupported() { - return mAdapter != null; + return mLocalBluetoothManager != null; } @Override - public ArraySet<PairedDevice> getPairedDevices() { - final ArraySet<PairedDevice> rt = new ArraySet<>(); - for (int i = 0; i < mDeviceInfo.size(); i++) { - final BluetoothDevice device = mDeviceInfo.keyAt(i); - final DeviceInfo info = mDeviceInfo.valueAt(i); - if (!info.bonded) continue; - final PairedDevice paired = new PairedDevice(); - paired.id = device.getAddress(); - paired.tag = device; - paired.name = device.getAliasName(); - paired.state = connectionStateToPairedDeviceState(info.connectionStateIndex); - rt.add(paired); - } - return rt; - } - - private static int connectionStateToPairedDeviceState(int index) { - int state = CONNECTION_STATES[index]; - if (state == BluetoothAdapter.STATE_CONNECTED) return PairedDevice.STATE_CONNECTED; - if (state == BluetoothAdapter.STATE_CONNECTING) return PairedDevice.STATE_CONNECTING; - if (state == BluetoothAdapter.STATE_DISCONNECTING) return PairedDevice.STATE_DISCONNECTING; - return PairedDevice.STATE_DISCONNECTED; + public void connect(final CachedBluetoothDevice device) { + if (mLocalBluetoothManager == null || device == null) return; + device.connect(true); } @Override - public void connect(final PairedDevice pd) { - connect(pd, true); - } - - @Override - public void disconnect(PairedDevice pd) { - connect(pd, false); - } - - 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(); - if (uuids == null) { - Log.w(TAG, "No uuids returned, aborting " + action + " for " + deviceToString(device)); - return; - } - 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) { - Log.w(TAG, "Device " + deviceToString(device) + " has an unsupported uuid: " - + uuidToString(uuid)); - continue; - } - 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); - 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)); - } - } + public void disconnect(CachedBluetoothDevice device) { + if (mLocalBluetoothManager == null || device == null) return; + device.disconnect(); } @Override public String getLastDeviceName() { - return mLastDevice != null ? mLastDevice.getAliasName() : null; + return mLastDevice != null ? mLastDevice.getName() : null; } - private void updateBondedDevices() { - mHandler.removeMessages(MSG_UPDATE_BONDED_DEVICES); - mHandler.sendEmptyMessage(MSG_UPDATE_BONDED_DEVICES); - } - - private void updateConnectionStates() { - mHandler.removeMessages(MSG_UPDATE_CONNECTION_STATES); - mHandler.removeMessages(MSG_UPDATE_SINGLE_CONNECTION_STATE); - mHandler.sendEmptyMessage(MSG_UPDATE_CONNECTION_STATES); + @Override + public Collection<CachedBluetoothDevice> getDevices() { + return mLocalBluetoothManager != null + ? mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy() + : null; } - private void updateConnectionState(BluetoothDevice device, int profile, int state) { - if (mHandler.hasMessages(MSG_UPDATE_CONNECTION_STATES)) { - // If we are about to update all the devices, then we don't need to update this one. - return; + private void firePairedDevicesChanged() { + for (Callback cb : mCallbacks) { + cb.onBluetoothDevicesChanged(); } - mHandler.obtainMessage(MSG_UPDATE_SINGLE_CONNECTION_STATE, profile, state, device) - .sendToTarget(); } - private void handleUpdateBondedDevices() { - if (mAdapter == null) return; - final Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices(); - for (DeviceInfo info : mDeviceInfo.values()) { - info.bonded = false; - } - int bondedCount = 0; - BluetoothDevice lastBonded = null; - if (bondedDevices != null) { - for (BluetoothDevice bondedDevice : bondedDevices) { - final boolean bonded = bondedDevice.getBondState() != BluetoothDevice.BOND_NONE; - updateInfo(bondedDevice).bonded = bonded; - if (bonded) { - bondedCount++; - lastBonded = bondedDevice; - } - } - } - if (mLastDevice == null && bondedCount == 1) { - mLastDevice = lastBonded; + private void fireStateChange() { + for (Callback cb : mCallbacks) { + fireStateChange(cb); } - updateConnectionStates(); - firePairedDevicesChanged(); } - private void handleUpdateConnectionStates() { - final int N = mDeviceInfo.size(); - for (int i = 0; i < N; i++) { - BluetoothDevice device = mDeviceInfo.keyAt(i); - DeviceInfo info = updateInfo(device); - info.connectionStateIndex = 0; - info.connectedProfiles.clear(); - for (int j = 0; j < mProfiles.size(); j++) { - int state = mProfiles.valueAt(j).getConnectionState(device); - handleUpdateConnectionState(device, mProfiles.keyAt(j), state); - } - } - handleConnectionChange(); - firePairedDevicesChanged(); + private void fireStateChange(Callback cb) { + cb.onBluetoothStateChange(mEnabled, mConnecting); } - private void handleUpdateConnectionState(BluetoothDevice device, int profile, int state) { - if (DEBUG) Log.d(TAG, "updateConnectionState " + BluetoothUtil.deviceToString(device) - + " " + BluetoothUtil.profileToString(profile) - + " " + BluetoothUtil.connectionStateToString(state)); - DeviceInfo info = updateInfo(device); - int stateIndex = 0; - for (int i = 0; i < CONNECTION_STATES.length; i++) { - if (CONNECTION_STATES[i] == state) { - stateIndex = i; - break; - } - } - info.profileStates.put(profile, stateIndex); - - info.connectionStateIndex = 0; - final int N = info.profileStates.size(); - for (int i = 0; i < N; i++) { - if (info.profileStates.valueAt(i) > info.connectionStateIndex) { - info.connectionStateIndex = info.profileStates.valueAt(i); - } - } - if (state == BluetoothProfile.STATE_CONNECTED) { - info.connectedProfiles.put(profile, true); - } else { - info.connectedProfiles.remove(profile); + private void updateConnected() { + if (mLastDevice != null && mLastDevice.isConnected()) { + // Our current device is still valid. + return; } - } - - private void handleConnectionChange() { - // 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 && - CONNECTION_STATES[mDeviceInfo.get(mLastDevice).connectionStateIndex] - != 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 (CONNECTION_STATES[info.connectionStateIndex] - == BluetoothProfile.STATE_CONNECTED) { - mLastDevice = device; - break; - } + for (CachedBluetoothDevice device : getDevices()) { + if (device.isConnected()) { + mLastDevice = device; } } } - 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(); - } - } - - private void setAdapterState(int adapterState) { - final boolean enabled = adapterState == BluetoothAdapter.STATE_ON; - if (mEnabled == enabled) return; - mEnabled = enabled; - fireStateChange(); - } - - private void setConnecting(boolean connecting) { - if (mConnecting == connecting) return; - mConnecting = connecting; + @Override + public void onBluetoothStateChanged(int bluetoothState) { + mEnabled = bluetoothState == BluetoothAdapter.STATE_ON; fireStateChange(); } - private void fireStateChange() { - for (Callback cb : mCallbacks) { - fireStateChange(cb); - } + @Override + public void onScanningStateChanged(boolean started) { + // Don't care. } - private void fireStateChange(Callback cb) { - cb.onBluetoothStateChange(mEnabled, mConnecting); + @Override + public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { + cachedDevice.registerCallback(this); + updateConnected(); + firePairedDevicesChanged(); } - private static int getProfileFromAction(String action) { - if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { - return BluetoothProfile.A2DP; - } else if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { - return BluetoothProfile.HEADSET; - } else if (BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { - return BluetoothProfile.A2DP_SINK; - } else if (BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { - return BluetoothProfile.HEADSET_CLIENT; - } else if (BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { - return BluetoothProfile.INPUT_DEVICE; - } else if (BluetoothMap.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { - return BluetoothProfile.MAP; - } else if (BluetoothPan.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { - return BluetoothProfile.PAN; - } - if (DEBUG) Log.d(TAG, "Unknown action " + action); - return -1; + @Override + public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { + updateConnected(); + firePairedDevicesChanged(); } - private final ServiceListener mProfileListener = new ServiceListener() { - @Override - public void onServiceDisconnected(int profile) { - if (DEBUG) Log.d(TAG, "Disconnected from " + BluetoothUtil.profileToString(profile)); - // We lost a profile, don't do any updates until it gets removed. - mHandler.removeMessages(MSG_UPDATE_CONNECTION_STATES); - mHandler.removeMessages(MSG_UPDATE_SINGLE_CONNECTION_STATE); - mHandler.obtainMessage(MSG_REM_PROFILE, profile, 0).sendToTarget(); - } - - @Override - public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (DEBUG) Log.d(TAG, "Connected to " + BluetoothUtil.profileToString(profile)); - mHandler.obtainMessage(MSG_ADD_PROFILE, profile, 0, proxy).sendToTarget(); - } - }; - - private final class Receiver extends BroadcastReceiver { - public void register() { - final IntentFilter filter = new IntentFilter(); - filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); - filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); - filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); - filter.addAction(BluetoothDevice.ACTION_ALIAS_CHANGED); - 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); - } - - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - - if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { - setAdapterState(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, ERROR)); - updateBondedDevices(); - if (DEBUG) Log.d(TAG, "ACTION_STATE_CHANGED " + mEnabled); - } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { - updateInfo(device); - final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, - ERROR); - mLastDevice = device; - if (DEBUG) Log.d(TAG, "ACTION_CONNECTION_STATE_CHANGED " - + connectionStateToString(state) + " " + deviceToString(device)); - setConnecting(state == BluetoothAdapter.STATE_CONNECTING); - } else if (action.equals(BluetoothDevice.ACTION_ALIAS_CHANGED)) { - updateInfo(device); - mLastDevice = device; - } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { - if (DEBUG) Log.d(TAG, "ACTION_BOND_STATE_CHANGED " + device); - updateBondedDevices(); - } else { - int profile = getProfileFromAction(intent.getAction()); - int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); - if (DEBUG) Log.d(TAG, "ACTION_CONNECTION_STATE_CHANGE " - + BluetoothUtil.profileToString(profile) - + " " + BluetoothUtil.connectionStateToString(state)); - if ((profile != -1) && (state != -1)) { - updateConnectionState(device, profile, state); - } - } - } + @Override + public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) { + updateConnected(); + firePairedDevicesChanged(); } - private DeviceInfo updateInfo(BluetoothDevice device) { - DeviceInfo info = mDeviceInfo.get(device); - info = info != null ? info : new DeviceInfo(); - mDeviceInfo.put(device, info); - return info; + @Override + public void onDeviceAttributesChanged() { + updateConnected(); + firePairedDevicesChanged(); } - private class H extends Handler { - public H(Looper l) { - super(l); - } - - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_UPDATE_CONNECTION_STATES: - handleUpdateConnectionStates(); - firePairedDevicesChanged(); - break; - case MSG_UPDATE_SINGLE_CONNECTION_STATE: - handleUpdateConnectionState((BluetoothDevice) msg.obj, msg.arg1, msg.arg2); - handleConnectionChange(); - firePairedDevicesChanged(); - break; - case MSG_UPDATE_BONDED_DEVICES: - handleUpdateBondedDevices(); - firePairedDevicesChanged(); - break; - case MSG_ADD_PROFILE: - mProfiles.put(msg.arg1, (BluetoothProfile) msg.obj); - handleUpdateConnectionStates(); - firePairedDevicesChanged(); - break; - case MSG_REM_PROFILE: - mProfiles.remove(msg.arg1); - handleUpdateConnectionStates(); - firePairedDevicesChanged(); - break; - } - }; - }; - - private static class DeviceInfo { - int connectionStateIndex = 0; - boolean bonded; // per getBondedDevices - SparseArray<Boolean> connectedProfiles = new SparseArray<>(); - SparseArray<Integer> profileStates = new SparseArray<>(); + @Override + public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { + mConnecting = state == BluetoothAdapter.STATE_CONNECTING; + mLastDevice = cachedDevice; + updateConnected(); + fireStateChange(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java deleted file mode 100644 index ed8ac2c..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.policy; - -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.BluetoothMap; -import android.bluetooth.BluetoothPan; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.BluetoothUuid; -import android.os.ParcelUuid; -import android.text.TextUtils; - -public class BluetoothUtil { - - public static String profileToString(int profile) { - if (profile == BluetoothProfile.HEADSET) return "HEADSET"; - if (profile == BluetoothProfile.A2DP) return "A2DP"; - if (profile == BluetoothProfile.AVRCP_CONTROLLER) return "AVRCP_CONTROLLER"; - 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) { - if (state == BluetoothProfile.STATE_CONNECTED) return "STATE_CONNECTED"; - if (state == BluetoothProfile.STATE_CONNECTING) return "STATE_CONNECTING"; - if (state == BluetoothProfile.STATE_DISCONNECTED) return "STATE_DISCONNECTED"; - if (state == BluetoothProfile.STATE_DISCONNECTING) return "STATE_DISCONNECTING"; - return "STATE_UNKNOWN"; - } - - public static String uuidToString(ParcelUuid uuid) { - if (BluetoothUuid.AudioSink.equals(uuid)) return "AudioSink"; - if (BluetoothUuid.AudioSource.equals(uuid)) return "AudioSource"; - if (BluetoothUuid.AdvAudioDist.equals(uuid)) return "AdvAudioDist"; - if (BluetoothUuid.HSP.equals(uuid)) return "HSP"; - if (BluetoothUuid.HSP_AG.equals(uuid)) return "HSP_AG"; - if (BluetoothUuid.Handsfree.equals(uuid)) return "Handsfree"; - if (BluetoothUuid.Handsfree_AG.equals(uuid)) return "Handsfree_AG"; - if (BluetoothUuid.AvrcpController.equals(uuid)) return "AvrcpController"; - if (BluetoothUuid.AvrcpTarget.equals(uuid)) return "AvrcpTarget"; - if (BluetoothUuid.ObexObjectPush.equals(uuid)) return "ObexObjectPush"; - if (BluetoothUuid.Hid.equals(uuid)) return "Hid"; - if (BluetoothUuid.Hogp.equals(uuid)) return "Hogp"; - if (BluetoothUuid.PANU.equals(uuid)) return "PANU"; - if (BluetoothUuid.NAP.equals(uuid)) return "NAP"; - if (BluetoothUuid.BNEP.equals(uuid)) return "BNEP"; - if (BluetoothUuid.PBAP_PSE.equals(uuid)) return "PBAP_PSE"; - if (BluetoothUuid.MAP.equals(uuid)) return "MAP"; - if (BluetoothUuid.MNS.equals(uuid)) return "MNS"; - if (BluetoothUuid.MAS.equals(uuid)) return "MAS"; - return uuid != null ? uuid.toString() : null; - } - - public static String connectionStateToString(int connectionState) { - if (connectionState == BluetoothAdapter.STATE_DISCONNECTED) return "STATE_DISCONNECTED"; - if (connectionState == BluetoothAdapter.STATE_CONNECTED) return "STATE_CONNECTED"; - if (connectionState == BluetoothAdapter.STATE_DISCONNECTING) return "STATE_DISCONNECTING"; - if (connectionState == BluetoothAdapter.STATE_CONNECTING) return "STATE_CONNECTING"; - return "ERROR"; - } - - public static String deviceToString(BluetoothDevice device) { - return device == null ? null : (device.getAddress() + '[' + device.getAliasName() + ']'); - } - - public static String uuidsToString(BluetoothDevice device) { - if (device == null) return null; - final ParcelUuid[] ids = device.getUuids(); - if (ids == null) return null; - final String[] tokens = new String[ids.length]; - for (int i = 0; i < tokens.length; i++) { - tokens[i] = uuidToString(ids[i]); - } - return TextUtils.join(",", tokens); - } - - public static int uuidToProfile(ParcelUuid uuid) { - if (BluetoothUuid.AudioSink.equals(uuid)) return BluetoothProfile.A2DP; - if (BluetoothUuid.AdvAudioDist.equals(uuid)) return BluetoothProfile.A2DP; - - if (BluetoothUuid.HSP.equals(uuid)) return BluetoothProfile.HEADSET; - if (BluetoothUuid.Handsfree.equals(uuid)) return BluetoothProfile.HEADSET; - - if (BluetoothUuid.MAP.equals(uuid)) return BluetoothProfile.MAP; - if (BluetoothUuid.MNS.equals(uuid)) return BluetoothProfile.MAP; - if (BluetoothUuid.MAS.equals(uuid)) return BluetoothProfile.MAP; - - 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; - } - - public static Profile getProfile(BluetoothProfile p) { - if (p instanceof BluetoothA2dp) return newProfile((BluetoothA2dp) p); - if (p instanceof BluetoothHeadset) return newProfile((BluetoothHeadset) p); - if (p instanceof BluetoothA2dpSink) return newProfile((BluetoothA2dpSink) p); - if (p instanceof BluetoothHeadsetClient) return newProfile((BluetoothHeadsetClient) p); - if (p instanceof BluetoothInputDevice) return newProfile((BluetoothInputDevice) p); - if (p instanceof BluetoothMap) return newProfile((BluetoothMap) p); - if (p instanceof BluetoothPan) return newProfile((BluetoothPan) p); - return null; - } - - private static Profile newProfile(final BluetoothA2dp a2dp) { - return new Profile() { - @Override - public boolean connect(BluetoothDevice device) { - return a2dp.connect(device); - } - - @Override - public boolean disconnect(BluetoothDevice device) { - return a2dp.disconnect(device); - } - }; - } - - private static Profile newProfile(final BluetoothHeadset headset) { - return new Profile() { - @Override - public boolean connect(BluetoothDevice device) { - return headset.connect(device); - } - - @Override - public boolean disconnect(BluetoothDevice device) { - return headset.disconnect(device); - } - }; - } - - private static Profile newProfile(final BluetoothA2dpSink sink) { - return new Profile() { - @Override - public boolean connect(BluetoothDevice device) { - return sink.connect(device); - } - - @Override - public boolean disconnect(BluetoothDevice device) { - return sink.disconnect(device); - } - }; - } - - private static Profile newProfile(final BluetoothHeadsetClient client) { - return new Profile() { - @Override - public boolean connect(BluetoothDevice device) { - return client.connect(device); - } - - @Override - public boolean disconnect(BluetoothDevice device) { - return client.disconnect(device); - } - }; - } - - private static Profile newProfile(final BluetoothInputDevice input) { - return new Profile() { - @Override - public boolean connect(BluetoothDevice device) { - return input.connect(device); - } - - @Override - public boolean disconnect(BluetoothDevice device) { - return input.disconnect(device); - } - }; - } - - private static Profile newProfile(final BluetoothMap map) { - return new Profile() { - @Override - public boolean connect(BluetoothDevice device) { - return map.connect(device); - } - - @Override - public boolean disconnect(BluetoothDevice device) { - return map.disconnect(device); - } - }; - } - - private static Profile newProfile(final BluetoothPan pan) { - return new Profile() { - @Override - public boolean connect(BluetoothDevice device) { - return pan.connect(device); - } - - @Override - public boolean disconnect(BluetoothDevice device) { - return pan.disconnect(device); - } - }; - } - - // common abstraction for supported profiles - public interface Profile { - boolean connect(BluetoothDevice device); - boolean disconnect(BluetoothDevice device); - } -} |