diff options
author | Jason Monk <jmonk@google.com> | 2015-01-05 16:34:35 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-01-05 16:34:35 +0000 |
commit | 2858ca9e282b10afd67da73885e3a25e82e510a6 (patch) | |
tree | 1e319f0b11ff980d7c8d2db912248b03e8cbea2e /packages/SystemUI/src | |
parent | fe3cdf015e42168954f20125e7c9f4495f9d4647 (diff) | |
parent | cf28f9b8830503605ff254a5ca8edd368e065a93 (diff) | |
download | frameworks_base-2858ca9e282b10afd67da73885e3a25e82e510a6.zip frameworks_base-2858ca9e282b10afd67da73885e3a25e82e510a6.tar.gz frameworks_base-2858ca9e282b10afd67da73885e3a25e82e510a6.tar.bz2 |
am cf28f9b8: am 4ae97d36: Post broadcasts to bg and cache bt state info
* commit 'cf28f9b8830503605ff254a5ca8edd368e065a93':
Post broadcasts to bg and cache bt state info
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java | 13 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java | 211 |
2 files changed, 184 insertions, 40 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 8b328aa..d6647af 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -69,9 +69,11 @@ import android.media.session.PlaybackState; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; +import android.os.HandlerThread; import android.os.IBinder; import android.os.Message; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -368,6 +370,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private ScreenPinningRequest mScreenPinningRequest; private int mNavigationIconHints = 0; + private HandlerThread mHandlerThread; // ensure quick settings is disabled until the current user makes it through the setup wizard private boolean mUserSetup = false; @@ -782,6 +785,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // set the inital view visibility setAreThereNotifications(); + // Background thread for any controllers that need it. + mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND); + mHandlerThread.start(); + // Other icons mLocationController = new LocationControllerImpl(mContext); // will post a notification mBatteryController = new BatteryController(mContext); @@ -800,7 +807,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, }); mNetworkController = new NetworkControllerImpl(mContext); mHotspotController = new HotspotControllerImpl(mContext); - mBluetoothController = new BluetoothControllerImpl(mContext); + mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper()); mSecurityController = new SecurityControllerImpl(mContext); if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) { mRotationLockController = new RotationLockControllerImpl(mContext); @@ -3445,6 +3452,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mWindowManager.removeViewImmediate(mNavigationBarView); mNavigationBarView = null; } + if (mHandlerThread != null) { + mHandlerThread.quitSafely(); + mHandlerThread = null; + } mContext.unregisterReceiver(mBroadcastReceiver); } 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 6bd986b..81e1e45 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java @@ -40,6 +40,9 @@ 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; @@ -51,7 +54,6 @@ 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 { @@ -68,6 +70,15 @@ public class BluetoothControllerImpl implements BluetoothController { 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>(); @@ -76,12 +87,16 @@ public class BluetoothControllerImpl implements BluetoothController { private final ArrayMap<BluetoothDevice, DeviceInfo> mDeviceInfo = new ArrayMap<>(); private final SparseArray<BluetoothProfile> mProfiles = new SparseArray<>(); + private final H mHandler; + private boolean mEnabled; private boolean mConnecting; private BluetoothDevice mLastDevice; - public BluetoothControllerImpl(Context context) { + public BluetoothControllerImpl(Context context, Looper bgLooper) { mContext = context; + mHandler = new H(bgLooper); + final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); mAdapter = bluetoothManager.getAdapter(); @@ -92,7 +107,7 @@ public class BluetoothControllerImpl implements BluetoothController { mReceiver.register(); setAdapterState(mAdapter.getState()); - updateBluetoothDevices(); + updateBondedDevices(); bindAllProfiles(); } @@ -116,8 +131,9 @@ public class BluetoothControllerImpl implements BluetoothController { private static String infoToString(DeviceInfo info) { return info == null ? null : ("connectionState=" + - connectionStateToString(info.connectionState) + ",bonded=" + info.bonded - + ",profiles=" + profilesToString(info.connectedProfiles)); + connectionStateToString(CONNECTION_STATES[info.connectionStateIndex]) + + ",bonded=" + info.bonded + ",profiles=" + + profilesToString(info.connectedProfiles)); } private static String profilesToString(SparseArray<?> profiles) { @@ -188,13 +204,14 @@ public class BluetoothControllerImpl implements BluetoothController { paired.id = device.getAddress(); paired.tag = device; paired.name = device.getAliasName(); - paired.state = connectionStateToPairedDeviceState(info.connectionState); + paired.state = connectionStateToPairedDeviceState(info.connectionStateIndex); rt.add(paired); } return rt; } - private static int connectionStateToPairedDeviceState(int state) { + 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; @@ -259,13 +276,31 @@ public class BluetoothControllerImpl implements BluetoothController { return mLastDevice != null ? mLastDevice.getAliasName() : null; } - private void updateBluetoothDevices() { + 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); + } + + 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; + } + 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; - info.connectionState = ERROR; - info.connectedProfiles.clear(); } int bondedCount = 0; BluetoothDevice lastBonded = null; @@ -279,32 +314,63 @@ public class BluetoothControllerImpl implements BluetoothController { } } } - final int N = mProfiles.size(); - final int[] connectionType = new int[1]; + if (mLastDevice == null && bondedCount == 1) { + mLastDevice = lastBonded; + } + 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 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++) { - 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)); - if (info != null) { - info.connectionState = CONNECTION_STATES[i]; - if (CONNECTION_STATES[i] == BluetoothProfile.STATE_CONNECTED) { - info.connectedProfiles.put(profile, true); - } - } - } + if (CONNECTION_STATES[i] == state) { + stateIndex = i; + break; } } - if (mLastDevice == null && bondedCount == 1) { - mLastDevice = lastBonded; + 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 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 && - mDeviceInfo.get(mLastDevice).connectionState != BluetoothProfile.STATE_CONNECTED) { + 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. @@ -312,13 +378,13 @@ public class BluetoothControllerImpl implements BluetoothController { for (int i = 0; i < size; i++) { BluetoothDevice device = mDeviceInfo.keyAt(i); DeviceInfo info = mDeviceInfo.valueAt(i); - if (info.connectionState == BluetoothProfile.STATE_CONNECTED) { + if (CONNECTION_STATES[info.connectionStateIndex] + == BluetoothProfile.STATE_CONNECTED) { mLastDevice = device; break; } } } - firePairedDevicesChanged(); } private void bindAllProfiles() { @@ -366,17 +432,40 @@ public class BluetoothControllerImpl implements BluetoothController { cb.onBluetoothStateChange(mEnabled, mConnecting); } + 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; + } + private final ServiceListener mProfileListener = new ServiceListener() { @Override public void onServiceDisconnected(int profile) { - mProfiles.remove(profile); - updateBluetoothDevices(); + 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) { - mProfiles.put(profile, proxy); - updateBluetoothDevices(); + if (DEBUG) Log.d(TAG, "Connected to " + BluetoothUtil.profileToString(profile)); + mHandler.obtainMessage(MSG_ADD_PROFILE, profile, 0, proxy).sendToTarget(); } }; @@ -401,8 +490,10 @@ public class BluetoothControllerImpl implements BluetoothController { 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); @@ -417,10 +508,17 @@ public class BluetoothControllerImpl implements BluetoothController { mLastDevice = device; } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { if (DEBUG) Log.d(TAG, "ACTION_BOND_STATE_CHANGED " + device); - // we'll update all bonded devices below + 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); + } } - // Always update bluetooth devices state. - updateBluetoothDevices(); } } @@ -431,9 +529,44 @@ public class BluetoothControllerImpl implements BluetoothController { return info; } + 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 connectionState = BluetoothAdapter.STATE_DISCONNECTED; + int connectionStateIndex = 0; boolean bonded; // per getBondedDevices SparseArray<Boolean> connectedProfiles = new SparseArray<>(); + SparseArray<Integer> profileStates = new SparseArray<>(); } } |