Merge "b/2680057 Fixed a bug where bt won't connect when the phone is docked (if Settings wasn't running)." into kraken
This commit is contained in:
@@ -18,6 +18,7 @@ package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.ServiceListener;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Notification;
|
||||
@@ -48,7 +49,7 @@ import java.util.Set;
|
||||
|
||||
public class DockService extends Service implements AlertDialog.OnMultiChoiceClickListener,
|
||||
DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
|
||||
CompoundButton.OnCheckedChangeListener {
|
||||
CompoundButton.OnCheckedChangeListener, ServiceListener {
|
||||
|
||||
private static final String TAG = "DockService";
|
||||
|
||||
@@ -101,6 +102,7 @@ public class DockService extends Service implements AlertDialog.OnMultiChoiceCli
|
||||
// Created in OnCreate()
|
||||
private volatile Looper mServiceLooper;
|
||||
private volatile ServiceHandler mServiceHandler;
|
||||
private Runnable mRunnable;
|
||||
private DockService mContext;
|
||||
private LocalBluetoothManager mBtManager;
|
||||
|
||||
@@ -138,6 +140,8 @@ public class DockService extends Service implements AlertDialog.OnMultiChoiceCli
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (DEBUG) Log.d(TAG, "onDestroy");
|
||||
mRunnable = null;
|
||||
LocalBluetoothProfileManager.removeServiceListener(this);
|
||||
if (mDialog != null) {
|
||||
mDialog.dismiss();
|
||||
mDialog = null;
|
||||
@@ -228,8 +232,8 @@ public class DockService extends Service implements AlertDialog.OnMultiChoiceCli
|
||||
// This method gets messages from both onStartCommand and mServiceHandler/mServiceLooper
|
||||
private synchronized void processMessage(Message msg) {
|
||||
int msgType = msg.what;
|
||||
int state = msg.arg1;
|
||||
int startId = msg.arg2;
|
||||
final int state = msg.arg1;
|
||||
final int startId = msg.arg2;
|
||||
boolean deferFinishCall = false;
|
||||
BluetoothDevice device = null;
|
||||
if (msg.obj != null) {
|
||||
@@ -271,12 +275,23 @@ public class DockService extends Service implements AlertDialog.OnMultiChoiceCli
|
||||
}
|
||||
|
||||
mDevice = device;
|
||||
if (mBtManager.getDockAutoConnectSetting(device.getAddress())) {
|
||||
// Setting == auto connect
|
||||
initBtSettings(mContext, device, state, false);
|
||||
applyBtSettings(mDevice, startId);
|
||||
|
||||
// Register first in case LocalBluetoothProfileManager
|
||||
// becomes ready after isManagerReady is called and it
|
||||
// would be too late to register a service listener.
|
||||
LocalBluetoothProfileManager.addServiceListener(this);
|
||||
if (LocalBluetoothProfileManager.isManagerReady()) {
|
||||
handleDocked(device, state, startId);
|
||||
// Not needed after all
|
||||
LocalBluetoothProfileManager.removeServiceListener(this);
|
||||
} else {
|
||||
createDialog(mContext, mDevice, state, startId);
|
||||
final BluetoothDevice d = device;
|
||||
mRunnable = new Runnable() {
|
||||
public void run() {
|
||||
handleDocked(d, state, startId);
|
||||
}
|
||||
};
|
||||
deferFinishCall = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -721,8 +736,21 @@ public class DockService extends Service implements AlertDialog.OnMultiChoiceCli
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void handleDocked(final BluetoothDevice device, final int state,
|
||||
final int startId) {
|
||||
if (mBtManager.getDockAutoConnectSetting(device.getAddress())) {
|
||||
// Setting == auto connect
|
||||
initBtSettings(mContext, device, state, false);
|
||||
applyBtSettings(mDevice, startId);
|
||||
} else {
|
||||
createDialog(mContext, device, state, startId);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void handleUndocked(Context context, LocalBluetoothManager localManager,
|
||||
BluetoothDevice device) {
|
||||
mRunnable = null;
|
||||
LocalBluetoothProfileManager.removeServiceListener(this);
|
||||
if (mDialog != null) {
|
||||
mDialog.dismiss();
|
||||
mDialog = null;
|
||||
@@ -778,4 +806,15 @@ public class DockService extends Service implements AlertDialog.OnMultiChoiceCli
|
||||
editor.commit();
|
||||
return;
|
||||
}
|
||||
|
||||
public synchronized void onServiceConnected() {
|
||||
if (mRunnable != null) {
|
||||
mRunnable.run();
|
||||
mRunnable = null;
|
||||
LocalBluetoothProfileManager.removeServiceListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceDisconnected() {
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,8 @@ import android.util.Log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -53,6 +55,29 @@ public abstract class LocalBluetoothProfileManager {
|
||||
BluetoothUuid.ObexObjectPush
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface for notifying BluetoothHeadset IPC clients when they have
|
||||
* been connected to the BluetoothHeadset service.
|
||||
*/
|
||||
public interface ServiceListener {
|
||||
/**
|
||||
* Called to notify the client when this proxy object has been
|
||||
* connected to the BluetoothHeadset service. Clients must wait for
|
||||
* this callback before making IPC calls on the BluetoothHeadset
|
||||
* service.
|
||||
*/
|
||||
public void onServiceConnected();
|
||||
|
||||
/**
|
||||
* Called to notify the client that this proxy object has been
|
||||
* disconnected from the BluetoothHeadset service. Clients must not
|
||||
* make IPC calls on the BluetoothHeadset service after this callback.
|
||||
* This callback will currently only occur if the application hosting
|
||||
* the BluetoothHeadset service, but may be called more often in future.
|
||||
*/
|
||||
public void onServiceDisconnected();
|
||||
}
|
||||
|
||||
// TODO: close profiles when we're shutting down
|
||||
private static Map<Profile, LocalBluetoothProfileManager> sProfileMap =
|
||||
new HashMap<Profile, LocalBluetoothProfileManager>();
|
||||
@@ -76,6 +101,26 @@ public abstract class LocalBluetoothProfileManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static LinkedList<ServiceListener> mServiceListeners = new LinkedList<ServiceListener>();
|
||||
|
||||
public static void addServiceListener(ServiceListener l) {
|
||||
mServiceListeners.add(l);
|
||||
}
|
||||
|
||||
public static void removeServiceListener(ServiceListener l) {
|
||||
mServiceListeners.remove(l);
|
||||
}
|
||||
|
||||
public static boolean isManagerReady() {
|
||||
// Getting just the headset profile is fine for now. Will need to deal with A2DP
|
||||
// and others if they aren't always in a ready state.
|
||||
LocalBluetoothProfileManager profileManager = sProfileMap.get(Profile.HEADSET);
|
||||
if (profileManager == null) {
|
||||
return sProfileMap.size() > 0;
|
||||
}
|
||||
return profileManager.isProfileReady();
|
||||
}
|
||||
|
||||
public static LocalBluetoothProfileManager getProfileManager(LocalBluetoothManager localManager,
|
||||
Profile profile) {
|
||||
// Note: This code assumes that "localManager" is same as the
|
||||
@@ -144,6 +189,8 @@ public abstract class LocalBluetoothProfileManager {
|
||||
return SettingsBtStatus.isConnectionStatusConnected(getConnectionStatus(device));
|
||||
}
|
||||
|
||||
public abstract boolean isProfileReady();
|
||||
|
||||
// TODO: int instead of enum
|
||||
public enum Profile {
|
||||
HEADSET(R.string.bluetooth_profile_headset),
|
||||
@@ -247,6 +294,11 @@ public abstract class LocalBluetoothProfileManager {
|
||||
return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfileReady() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,6 +308,7 @@ public abstract class LocalBluetoothProfileManager {
|
||||
implements BluetoothHeadset.ServiceListener {
|
||||
private BluetoothHeadset mService;
|
||||
private Handler mUiHandler = new Handler();
|
||||
private boolean profileReady = false;
|
||||
|
||||
public HeadsetProfileManager(LocalBluetoothManager localManager) {
|
||||
super(localManager);
|
||||
@@ -263,6 +316,7 @@ public abstract class LocalBluetoothProfileManager {
|
||||
}
|
||||
|
||||
public void onServiceConnected() {
|
||||
profileReady = true;
|
||||
// This could be called on a non-UI thread, funnel to UI thread.
|
||||
mUiHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
@@ -277,9 +331,28 @@ public abstract class LocalBluetoothProfileManager {
|
||||
BluetoothHeadset.STATE_CONNECTED);
|
||||
}
|
||||
});
|
||||
|
||||
if (mServiceListeners.size() > 0) {
|
||||
Iterator<ServiceListener> it = mServiceListeners.iterator();
|
||||
while(it.hasNext()) {
|
||||
it.next().onServiceConnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceDisconnected() {
|
||||
profileReady = false;
|
||||
if (mServiceListeners.size() > 0) {
|
||||
Iterator<ServiceListener> it = mServiceListeners.iterator();
|
||||
while(it.hasNext()) {
|
||||
it.next().onServiceDisconnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfileReady() {
|
||||
return profileReady;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -423,6 +496,11 @@ public abstract class LocalBluetoothProfileManager {
|
||||
public void setPreferred(BluetoothDevice device, boolean preferred) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfileReady() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int convertState(int oppState) {
|
||||
switch (oppState) {
|
||||
|
Reference in New Issue
Block a user