From d97daa064b35ee0c2b73547d46f97fa88d2da4e9 Mon Sep 17 00:00:00 2001 From: Jaikumar Ganesh Date: Fri, 19 Jun 2009 16:10:50 -0700 Subject: [PATCH] Handle class and name changed actions with DeviceFound signals. When the class or name of a device changed, due to name resolution or otherwise, we were not updating the cache. --- .../bluetooth/BluetoothEventRedirector.java | 41 +++++++------ .../bluetooth/LocalBluetoothDevice.java | 27 ++++++-- .../LocalBluetoothDeviceManager.java | 61 ++++++++++--------- 3 files changed, 77 insertions(+), 52 deletions(-) diff --git a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java index af64c98f1b5..55b2b77b00b 100644 --- a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java +++ b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java @@ -17,6 +17,7 @@ package com.android.settings.bluetooth; import android.bluetooth.BluetoothA2dp; +import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothError; import android.bluetooth.BluetoothHeadset; @@ -37,39 +38,41 @@ import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile; public class BluetoothEventRedirector { private static final String TAG = "BluetoothEventRedirector"; private static final boolean V = LocalBluetoothManager.V; - + private LocalBluetoothManager mManager; - + private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (V) { Log.v(TAG, "Received " + intent.getAction()); } - + String action = intent.getAction(); String address = intent.getStringExtra(BluetoothIntent.ADDRESS); - + if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) { int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE, BluetoothError.ERROR); mManager.setBluetoothStateInt(state); } else if (action.equals(BluetoothIntent.DISCOVERY_STARTED_ACTION)) { mManager.onScanningStateChanged(true); - + } else if (action.equals(BluetoothIntent.DISCOVERY_COMPLETED_ACTION)) { mManager.onScanningStateChanged(false); - + } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION)) { short rssi = intent.getShortExtra(BluetoothIntent.RSSI, Short.MIN_VALUE); - mManager.getLocalDeviceManager().onDeviceAppeared(address, rssi); - + int btClass = intent.getIntExtra(BluetoothIntent.CLASS, BluetoothClass.ERROR); + String name = intent.getStringExtra(BluetoothIntent.NAME); + mManager.getLocalDeviceManager().onDeviceAppeared(address, rssi, btClass, name); + } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION)) { mManager.getLocalDeviceManager().onDeviceDisappeared(address); - + } else if (action.equals(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION)) { mManager.getLocalDeviceManager().onDeviceNameUpdated(address); - + } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) { int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE, BluetoothError.ERROR); @@ -82,7 +85,7 @@ public class BluetoothEventRedirector { mManager.getLocalDeviceManager().onBondingError(address, reason); } } - + } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) { int newState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE, 0); int oldState = intent.getIntExtra(BluetoothIntent.HEADSET_PREVIOUS_STATE, 0); @@ -107,7 +110,7 @@ public class BluetoothEventRedirector { } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION)) { mManager.getLocalDeviceManager().onBtClassChanged(address); - + } } }; @@ -118,29 +121,29 @@ public class BluetoothEventRedirector { public void start() { IntentFilter filter = new IntentFilter(); - + // Bluetooth on/off broadcasts filter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION); - + // Discovery broadcasts filter.addAction(BluetoothIntent.DISCOVERY_STARTED_ACTION); filter.addAction(BluetoothIntent.DISCOVERY_COMPLETED_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION); filter.addAction(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION); - + // Pairing broadcasts filter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION); - + // Fine-grained state broadcasts filter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION); filter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION); - + mManager.getContext().registerReceiver(mBroadcastReceiver, filter); } - + public void stop() { - mManager.getContext().unregisterReceiver(mBroadcastReceiver); + mManager.getContext().unregisterReceiver(mBroadcastReceiver); } } diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java index 9a069331f3e..53ba44f9de0 100644 --- a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java +++ b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java @@ -96,7 +96,7 @@ public class LocalBluetoothDevice implements Comparable { this.profile = profile; this.timeSent = 0; } - + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -147,7 +147,7 @@ public class LocalBluetoothDevice implements Comparable { } } } - + private boolean pruneQueue(BluetoothJob job) { boolean removedStaleItems = false; long now = System.currentTimeMillis(); @@ -186,7 +186,7 @@ public class LocalBluetoothDevice implements Comparable { private boolean processCommand(BluetoothJob job) { boolean successful = false; if (job.timeSent == 0) { - job.timeSent = System.currentTimeMillis(); + job.timeSent = System.currentTimeMillis(); switch (job.command) { case CONNECT: successful = connectInt(job.device, job.profile); @@ -448,7 +448,7 @@ public class LocalBluetoothDevice implements Comparable { public void unpair() { synchronized (workQueue) { // Remove any pending commands for this device - boolean processNow = false; + boolean processNow = false; Iterator it = workQueue.iterator(); while (it.hasNext()) { BluetoothJob job = it.next(); @@ -494,6 +494,17 @@ public class LocalBluetoothDevice implements Comparable { return mName; } + public void setName(String name) { + if (!mName.equals(name)) { + if (TextUtils.isEmpty(name)) { + mName = mAddress; + } else { + mName = name; + } + dispatchAttributesChanged(); + } + } + public void refreshName() { fetchName(); dispatchAttributesChanged(); @@ -607,6 +618,14 @@ public class LocalBluetoothDevice implements Comparable { dispatchAttributesChanged(); } + public void setBtClass(int btClass) { + if (mBtClass != btClass && btClass != BluetoothClass.ERROR) { + mBtClass = btClass; + LocalBluetoothProfileManager.fill(mBtClass, mProfiles); + dispatchAttributesChanged(); + } + } + public int getSummary() { // TODO: clean up int oneOffSummary = getOneOffSummary(); diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java b/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java index 2c70fd2c84b..819d4826c11 100644 --- a/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java +++ b/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java @@ -34,7 +34,7 @@ public class LocalBluetoothDeviceManager { final LocalBluetoothManager mLocalManager; final List mCallbacks; - + final List mDevices = new ArrayList(); public LocalBluetoothDeviceManager(LocalBluetoothManager localManager) { @@ -47,7 +47,7 @@ public class LocalBluetoothDeviceManager { BluetoothDevice manager = mLocalManager.getBluetoothManager(); String[] bondedAddresses = manager.listBonds(); if (bondedAddresses == null) return false; - + boolean deviceAdded = false; for (String address : bondedAddresses) { LocalBluetoothDevice device = findDevice(address); @@ -58,55 +58,58 @@ public class LocalBluetoothDeviceManager { deviceAdded = true; } } - + return deviceAdded; } - + public synchronized List getDevicesCopy() { return new ArrayList(mDevices); } - + void onBluetoothStateChanged(boolean enabled) { if (enabled) { readPairedDevices(); } } - public synchronized void onDeviceAppeared(String address, short rssi) { + public synchronized void onDeviceAppeared(String address, short rssi, int btClass, + String name) { boolean deviceAdded = false; - + LocalBluetoothDevice device = findDevice(address); if (device == null) { device = new LocalBluetoothDevice(mLocalManager.getContext(), address); mDevices.add(device); deviceAdded = true; } - + device.setRssi(rssi); + device.setBtClass(btClass); + device.setName(name); device.setVisible(true); - + if (deviceAdded) { dispatchDeviceAdded(device); } } - + public synchronized void onDeviceDisappeared(String address) { LocalBluetoothDevice device = findDevice(address); if (device == null) return; - + device.setVisible(false); checkForDeviceRemoval(device); } - + private void checkForDeviceRemoval(LocalBluetoothDevice device) { if (device.getBondState() == BluetoothDevice.BOND_NOT_BONDED && !device.isVisible()) { // If device isn't paired, remove it altogether mDevices.remove(device); dispatchDeviceDeleted(device); - } + } } - + public synchronized void onDeviceNameUpdated(String address) { LocalBluetoothDevice device = findDevice(address); if (device != null) { @@ -115,21 +118,21 @@ public class LocalBluetoothDeviceManager { } public synchronized LocalBluetoothDevice findDevice(String address) { - + for (int i = mDevices.size() - 1; i >= 0; i--) { LocalBluetoothDevice device = mDevices.get(i); - + if (device.getAddress().equals(address)) { return device; } } - + return null; } - + /** * Attempts to get the name of a remote device, otherwise returns the address. - * + * * @param address The address. * @return The name, or if unavailable, the address. */ @@ -137,17 +140,17 @@ public class LocalBluetoothDeviceManager { LocalBluetoothDevice device = findDevice(address); return device != null ? device.getName() : address; } - + private void dispatchDeviceAdded(LocalBluetoothDevice device) { synchronized (mCallbacks) { for (Callback callback : mCallbacks) { callback.onDeviceAdded(device); } } - + // TODO: divider between prev paired/connected and scanned } - + private void dispatchDeviceDeleted(LocalBluetoothDevice device) { synchronized (mCallbacks) { for (Callback callback : mCallbacks) { @@ -176,7 +179,7 @@ public class LocalBluetoothDeviceManager { /** * Called when there is a bonding error. - * + * * @param address The address of the remote device. * @param reason The reason, one of the error reasons from * BluetoothDevice.UNBOND_REASON_* @@ -199,7 +202,7 @@ public class LocalBluetoothDeviceManager { } mLocalManager.showError(address, R.string.bluetooth_error_title, errorMsg); } - + public synchronized void onProfileStateChanged(String address, Profile profile, int newProfileState) { LocalBluetoothDevice device = findDevice(address); @@ -208,11 +211,11 @@ public class LocalBluetoothDeviceManager { device.onProfileStateChanged(profile, newProfileState); device.refresh(); } - + public synchronized void onConnectingError(String address) { LocalBluetoothDevice device = findDevice(address); if (device == null) return; - + /* * Go through the device's delegate so we don't spam the user with * errors connecting to different profiles, and instead make sure the @@ -220,10 +223,10 @@ public class LocalBluetoothDeviceManager { */ device.showConnectingError(); } - + public synchronized void onScanningStateChanged(boolean started) { if (!started) return; - + // If starting a new scan, clear old visibility for (int i = mDevices.size() - 1; i >= 0; i--) { LocalBluetoothDevice device = mDevices.get(i); @@ -231,7 +234,7 @@ public class LocalBluetoothDeviceManager { checkForDeviceRemoval(device); } } - + public synchronized void onBtClassChanged(String address) { LocalBluetoothDevice device = findDevice(address); if (device != null) {