am a1f463cb: Merge "Remove Profile Auto connection specific logic" into jb-mr1-dev

* commit 'a1f463cb1930e806420844d4915def2dcfe7ae72':
  Remove Profile Auto connection specific logic
This commit is contained in:
Matthew Xie
2012-08-08 00:35:29 -07:00
committed by Android Git Automerger
10 changed files with 165 additions and 262 deletions

View File

@@ -56,13 +56,11 @@ final class A2dpProfile implements LocalBluetoothProfile {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (V) Log.d(TAG,"Bluetooth service connected");
mService = (BluetoothA2dp) proxy;
mProfileManager.setA2dpServiceUp(true);
mIsProfileReady=true;
}
public void onServiceDisconnected(int profile) {
if (V) Log.d(TAG,"Bluetooth service disconnected");
mProfileManager.setA2dpServiceUp(false);
mIsProfileReady=false;
}
}
@@ -106,21 +104,11 @@ final class A2dpProfile implements LocalBluetoothProfile {
public boolean disconnect(BluetoothDevice device) {
if (mService == null) return false;
return mService.disconnect(device);
}
// This function is added as the AUTO CONNECT priority could not be set by using setPreferred(),
// as setPreferred() takes only boolean input but getPreferred() supports interger output.
// Also this need not implemented by all profiles so this has been added here.
public void enableAutoConnect(BluetoothDevice device, boolean enable) {
if (mService == null) return;
if (enable) {
mService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
} else {
if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
}
// Downgrade priority as user is disconnecting the headset.
if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
}
return mService.disconnect(device);
}
public int getConnectionStatus(BluetoothDevice device) {
@@ -150,13 +138,6 @@ final class A2dpProfile implements LocalBluetoothProfile {
mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
}
}
public void setUnbonded(BluetoothDevice device)
{
if (mService == null) return;
mService.setPriority(device, BluetoothProfile.PRIORITY_UNDEFINED);
}
boolean isA2dpPlaying() {
if (mService == null) return false;
List<BluetoothDevice> sinks = mService.getConnectedDevices();

View File

@@ -101,9 +101,6 @@ final class BluetoothEventManager {
// Dock event broadcasts
addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());
// Connect other profiles broadcast
addHandler(BluetoothProfile.ACTION_CONNECT_OTHER_PROFILES, new ConnectOtherProfilesHandler());
mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter);
}
@@ -372,13 +369,6 @@ final class BluetoothEventManager {
}
}
}
private class ConnectOtherProfilesHandler implements Handler {
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
mProfileManager.handleConnectOtherProfiles(device);
}
}
boolean readPairedDevices() {
Set<BluetoothDevice> bondedDevices = mLocalAdapter.getBondedDevices();
if (bondedDevices == null) {

View File

@@ -119,30 +119,6 @@ final class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
Log.d(TAG, "onProfileStateChanged: profile " + profile +
" newProfileState " + newProfileState);
}
if (profile instanceof HeadsetProfile) {
if (newProfileState == BluetoothProfile.STATE_CONNECTED) {
if (BluetoothProfile.PRIORITY_AUTO_CONNECT != profile.getPreferred(mDevice))
mProfileManager.enableAutoConnectForHf(mDevice, true);
} else if (newProfileState == BluetoothProfile.STATE_DISCONNECTED) {
// dont reset auto connect priority when bluetooth turned off
if ((BluetoothAdapter.STATE_ON == mLocalAdapter.getBluetoothState())
|| (BluetoothAdapter.STATE_TURNING_ON == mLocalAdapter.getBluetoothState())) {
mProfileManager.enableAutoConnectForHf(mDevice, false);
}
}
} else if (profile instanceof A2dpProfile ) {
if (newProfileState == BluetoothProfile.STATE_CONNECTED) {
if (BluetoothProfile.PRIORITY_AUTO_CONNECT != profile.getPreferred(mDevice))
mProfileManager.enableAutoConnectForA2dp(mDevice,true);
} else if (newProfileState == BluetoothProfile.STATE_DISCONNECTED) {
// dont reset auto connect priority when bluetooth turned off
if ((BluetoothAdapter.STATE_ON == mLocalAdapter.getBluetoothState())
|| (BluetoothAdapter.STATE_TURNING_ON == mLocalAdapter.getBluetoothState())) {
mProfileManager.enableAutoConnectForA2dp(mDevice, false);
}
}
}
mProfileConnectionState.put(profile, newProfileState);
if (newProfileState == BluetoothProfile.STATE_CONNECTED) {
if (!mProfiles.contains(profile)) {
@@ -180,6 +156,14 @@ final class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
for (LocalBluetoothProfile profile : mProfiles) {
disconnect(profile);
}
// Disconnect PBAP server in case its connected
// This is to ensure all the profiles are disconnected as some CK/Hs do not
// disconnect PBAP connection when HF connection is brought down
PbapServerProfile PbapProfile = mProfileManager.getPbapProfile();
if (PbapProfile.getConnectionStatus(mDevice) == BluetoothProfile.STATE_CONNECTED)
{
PbapProfile.disconnect(mDevice);
}
}
void disconnect(LocalBluetoothProfile profile) {
@@ -507,23 +491,11 @@ final class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
.elapsedRealtime()) {
connectWithoutResettingTimer(false);
}
// On an incoming pairing, set all the available profiles as preferred.
for (LocalBluetoothProfile profile : mProfiles) {
profile.setPreferred(mDevice, true);
}
dispatchAttributesChanged();
}
// Clear service priority of Hid, A2DP and Headset profiles on unbond
private void clearProfilePriorities() {
for (LocalBluetoothProfile profile : mProfiles) {
profile.setUnbonded(mDevice);
}
}
void onBondingStateChanged(int bondState) {
if (bondState == BluetoothDevice.BOND_NONE) {
clearProfilePriorities();
mProfiles.clear();
mConnectAfterPairing = false; // cancel auto-connect
setPhonebookPermissionChoice(PHONEBOOK_ACCESS_UNKNOWN);

View File

@@ -78,14 +78,12 @@ final class HeadsetProfile implements LocalBluetoothProfile {
}
mProfileManager.callServiceConnectedListeners();
mProfileManager.setHfServiceUp(true);
mIsProfileReady=true;
}
public void onServiceDisconnected(int profile) {
if (V) Log.d(TAG,"Bluetooth service disconnected");
mProfileManager.callServiceDisconnectedListeners();
mProfileManager.setHfServiceUp(false);
mIsProfileReady=false;
}
}
@@ -167,12 +165,6 @@ final class HeadsetProfile implements LocalBluetoothProfile {
}
}
public void setUnbonded(BluetoothDevice device)
{
if (mService == null) return;
mService.setPriority(device, BluetoothProfile.PRIORITY_UNDEFINED);
}
public List<BluetoothDevice> getConnectedDevices() {
if (mService == null) return new ArrayList<BluetoothDevice>(0);
return mService.getDevicesMatchingConnectionStates(
@@ -181,21 +173,6 @@ final class HeadsetProfile implements LocalBluetoothProfile {
BluetoothProfile.STATE_DISCONNECTING});
}
// This function is added as the AUTO CONNECT priority could not be set by using setPreferred(),
// as setPreferred() takes only boolean input but getPreferred() supports interger output.
// Also this need not implemented by all profiles so this has been added here.
public void enableAutoConnect(BluetoothDevice device, boolean enable) {
if (mService == null) return;
if (enable) {
mService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
} else {
if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
}
}
}
public String toString() {
return NAME;
}

6
src/com/android/settings/bluetooth/HidProfile.java Normal file → Executable file
View File

@@ -118,12 +118,6 @@ final class HidProfile implements LocalBluetoothProfile {
}
}
public void setUnbonded(BluetoothDevice device)
{
if (mService == null) return;
mService.setPriority(device, BluetoothProfile.PRIORITY_UNDEFINED);
}
public String toString() {
return NAME;
}

View File

@@ -47,8 +47,6 @@ interface LocalBluetoothProfile {
void setPreferred(BluetoothDevice device, boolean preferred);
void setUnbonded(BluetoothDevice device);
boolean isProfileReady();
/** Display order for device profile settings. */

View File

@@ -21,6 +21,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothPbap;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
@@ -43,13 +44,6 @@ import java.util.List;
*/
final class LocalBluetoothProfileManager {
private static final String TAG = "LocalBluetoothProfileManager";
private static final int CONNECT_HF_OR_A2DP = 1;
private static final int CONNECT_OTHER_PROFILES = 2;
// If either a2dp or hf is connected and if the other profile conneciton is not
// happening with the timeout , the other profile(a2dp or hf) will be inititate connection.
// Give reasonable timeout for the device to initiate the other profile connection.
private static final int CONNECT_HF_OR_A2DP_TIMEOUT = 6000;
/** Singleton instance. */
private static LocalBluetoothProfileManager sInstance;
@@ -88,47 +82,7 @@ final class LocalBluetoothProfileManager {
private final HidProfile mHidProfile;
private OppProfile mOppProfile;
private final PanProfile mPanProfile;
private boolean isHfServiceUp;
private boolean isA2dpServiceUp;
private boolean isHfA2dpConnectMessagePosted;
private final Handler hfA2dpConnectHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (this) {
if (isA2dpConnectRequired((BluetoothDevice)msg.obj)) {
mA2dpProfile.connect((BluetoothDevice)msg.obj);
} else if (isHfConnectRequired((BluetoothDevice)msg.obj)) {
mHeadsetProfile.connect((BluetoothDevice)msg.obj);
}
isHfA2dpConnectMessagePosted =false;
}
}
};
private final Handler connectOtherProfilesHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (this) {
// Connect all the profiles which are enabled
// Right now hf/a2dp profiles connect is handled here
List<BluetoothDevice> hfConnDevList= mHeadsetProfile.getConnectedDevices();
if (hfConnDevList.isEmpty() && mHeadsetProfile.isPreferred((BluetoothDevice)msg.obj))
mHeadsetProfile.connect((BluetoothDevice)msg.obj);
else
Log.d(TAG,"Hf device is not preferred or already Hf connected device exist");
List<BluetoothDevice> a2dpConnDevList= mA2dpProfile.getConnectedDevices();
if (a2dpConnDevList.isEmpty() && mA2dpProfile.isPreferred((BluetoothDevice)msg.obj))
mA2dpProfile.connect((BluetoothDevice)msg.obj);
else
Log.d(TAG,"A2dp device is not preferred or already a2dp connected device exist");
}
}
};
private final PbapServerProfile mPbapProfile;
/**
* Mapping from profile name, e.g. "HEADSET" to profile object.
@@ -165,6 +119,10 @@ final class LocalBluetoothProfileManager {
addPanProfile(mPanProfile, PanProfile.NAME,
BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
//Create PBAP server profile, but do not add it to list of profiles
// as we do not need to monitor the profile as part of profile list
mPbapProfile = new PbapServerProfile(context);
Log.d(TAG, "LocalBluetoothProfileManager construction complete");
}
@@ -273,21 +231,6 @@ final class LocalBluetoothProfileManager {
cachedDevice.onProfileStateChanged(mProfile, newState);
cachedDevice.refresh();
if ((mProfile instanceof HeadsetProfile)||(mProfile instanceof A2dpProfile)) {
if ((BluetoothProfile.STATE_CONNECTED == newState)&&
(!isHfA2dpConnectMessagePosted)) {
Message mes = hfA2dpConnectHandler.obtainMessage(CONNECT_HF_OR_A2DP);
mes.obj = device;
hfA2dpConnectHandler.sendMessageDelayed(mes,CONNECT_HF_OR_A2DP_TIMEOUT);
Log.i(TAG,"Message posted for hf/a2dp connection");
isHfA2dpConnectMessagePosted = true;
} else if (isHfA2dpConnectMessagePosted) {
hfA2dpConnectHandler.removeMessages(CONNECT_HF_OR_A2DP);
Log.i(TAG,"Message removed for hf/a2dp connection");
isHfA2dpConnectMessagePosted =false;
}
}
}
}
@@ -331,66 +274,6 @@ final class LocalBluetoothProfileManager {
}
}
synchronized void setHfServiceUp(boolean isUp) {
isHfServiceUp = isUp;
if (isHfServiceUp && isA2dpServiceUp) {
// connect hf and then a2dp
// this order is maintained as per the white paper
handleAutoConnect(mHeadsetProfile);
handleAutoConnect(mA2dpProfile);
}
}
synchronized void setA2dpServiceUp(boolean isUp) {
isA2dpServiceUp= isUp;
if (isHfServiceUp && isA2dpServiceUp) {
// connect hf and then a2dp
// this order is maintained as per the white paper
handleAutoConnect(mHeadsetProfile);
handleAutoConnect(mA2dpProfile);
}
}
private void handleAutoConnect(LocalBluetoothProfile profile) {
Set<BluetoothDevice> bondedDevices = mLocalAdapter.getBondedDevices();
for (BluetoothDevice device : bondedDevices) {
if (profile.getPreferred(device) ==
BluetoothProfile.PRIORITY_AUTO_CONNECT) {
Log.d(TAG,"handleAutoConnect for device");
CachedBluetoothDevice cacheDevice = mDeviceManager.findDevice(device);
if (null == cacheDevice)
{
Log.w(TAG,"Dev not found in cached dev list. Adding the dev to cached list");
cacheDevice = mDeviceManager.addDevice(mLocalAdapter,
LocalBluetoothProfileManager.this, device);
}
cacheDevice.connectInt(profile);
break;
}
}
}
public void enableAutoConnectForHf(BluetoothDevice device,boolean enable) {
mHeadsetProfile.enableAutoConnect(device,enable);
}
public void enableAutoConnectForA2dp(BluetoothDevice device,boolean enable) {
mA2dpProfile.enableAutoConnect(device,enable);
}
public void handleConnectOtherProfiles(BluetoothDevice device) {
if (device != null){
// Remove previous messages if any
connectOtherProfilesHandler.removeMessages(CONNECT_OTHER_PROFILES);
Message mes = connectOtherProfilesHandler.obtainMessage(CONNECT_OTHER_PROFILES);
mes.obj = device;
connectOtherProfilesHandler.sendMessageDelayed(mes,CONNECT_HF_OR_A2DP_TIMEOUT);
Log.i(TAG,"Message posted for connection other Profiles ");
} else {
Log.e(TAG,"Device = Null received in handleConnectOtherProfiles ");
}
}
// This is called by DockService, so check Headset and A2DP.
public synchronized boolean isManagerReady() {
// Getting just the headset profile is fine for now. Will need to deal with A2DP
@@ -414,6 +297,11 @@ final class LocalBluetoothProfileManager {
return mHeadsetProfile;
}
PbapServerProfile getPbapProfile(){
return mPbapProfile;
}
/**
* Fill in a list of LocalBluetoothProfile objects that are supported by
* the local device and the remote device.
@@ -473,34 +361,4 @@ final class LocalBluetoothProfileManager {
}
}
private boolean isHfConnectRequired(BluetoothDevice device) {
List<BluetoothDevice> a2dpConnDevList= mA2dpProfile.getConnectedDevices();
List<BluetoothDevice> hfConnDevList= mHeadsetProfile.getConnectedDevices();
// If both hf and a2dp is connected hf connection is not required
// Hf connection is required only when a2dp is connected but
// hf connect did no happen untill CONNECT_HF_OR_A2DP_TIMEOUT
if (!a2dpConnDevList.isEmpty() && !hfConnDevList.isEmpty())
return false;
if (hfConnDevList.isEmpty() && mHeadsetProfile.isPreferred(device))
return true;
return false;
}
private boolean isA2dpConnectRequired(BluetoothDevice device) {
List<BluetoothDevice> a2dpConnDevList= mA2dpProfile.getConnectedDevices();
List<BluetoothDevice> hfConnDevList= mHeadsetProfile.getConnectedDevices();
// If both hf and a2dp is connected a2dp connection is not required
// A2dp connection is required only when hf is connected but
// a2dp connect did no happen until CONNECT_HF_OR_A2DP_TIMEOUT
if (!a2dpConnDevList.isEmpty() && !hfConnDevList.isEmpty())
return false;
if (a2dpConnDevList.isEmpty() && mA2dpProfile.isPreferred(device))
return true;
return false;
}
}

4
src/com/android/settings/bluetooth/OppProfile.java Normal file → Executable file
View File

@@ -63,10 +63,6 @@ final class OppProfile implements LocalBluetoothProfile {
public void setPreferred(BluetoothDevice device, boolean preferred) {
}
public void setUnbonded(BluetoothDevice device) {
// Settings app doesn't handle OPP
}
public boolean isProfileReady() {
return true;
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (C) 2011 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.settings.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothPbap;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.util.Log;
import com.android.settings.R;
import java.util.HashMap;
import java.util.List;
/**
*PBAPServer Profile
*/
final class PbapServerProfile implements LocalBluetoothProfile {
private static final String TAG = "PbapServerProfile";
private static boolean V = true;
private BluetoothPbap mService;
private boolean mIsProfileReady;
static final String NAME = "PBAP Server";
// Order of this profile in device profiles list
private static final int ORDINAL = 6;
// These callbacks run on the main thread.
private final class PbapServiceListener
implements BluetoothPbap.ServiceListener {
public void onServiceConnected(BluetoothPbap proxy) {
if (V) Log.d(TAG,"Bluetooth service connected");
mService = (BluetoothPbap) proxy;
mIsProfileReady=true;
}
public void onServiceDisconnected() {
if (V) Log.d(TAG,"Bluetooth service disconnected");
mIsProfileReady=false;
}
}
public boolean isProfileReady() {
return mIsProfileReady;
}
PbapServerProfile(Context context) {
BluetoothPbap pbap = new BluetoothPbap(context, new PbapServiceListener());
}
public boolean isConnectable() {
return true;
}
public boolean isAutoConnectable() {
return false;
}
public boolean connect(BluetoothDevice device) {
/*Can't connect from server */
return false;
}
public boolean disconnect(BluetoothDevice device) {
if (mService == null) return false;
return mService.disconnect();
}
public int getConnectionStatus(BluetoothDevice device) {
if (mService == null) {
return BluetoothProfile.STATE_DISCONNECTED;
}
if (mService.isConnected(device))
return BluetoothProfile.STATE_CONNECTED;
else
return BluetoothProfile.STATE_DISCONNECTED;
}
public boolean isPreferred(BluetoothDevice device) {
return false;
}
public int getPreferred(BluetoothDevice device) {
return -1;
}
public void setPreferred(BluetoothDevice device, boolean preferred) {
// ignore: isPreferred is always true for PBAP
}
public String toString() {
return NAME;
}
public int getOrdinal() {
return ORDINAL;
}
public int getNameResource(BluetoothDevice device) {
return 0;
}
public int getSummaryResourceForDevice(BluetoothDevice device) {
return 0;
}
public int getDrawableResource(BluetoothClass btClass) {
return 0;
}
protected void finalize() {
if (V) Log.d(TAG, "finalize()");
if (mService != null) {
try {
mService.close();
mService = null;
}catch (Throwable t) {
Log.w(TAG, "Error cleaning up PBAP proxy", t);
}
}
}
}

5
src/com/android/settings/bluetooth/PanProfile.java Normal file → Executable file
View File

@@ -117,11 +117,6 @@ final class PanProfile implements LocalBluetoothProfile {
// ignore: isPreferred is always true for PAN
}
public void setUnbonded(BluetoothDevice device)
{
// ignore: PAN profile cannot be disabled
}
public String toString() {
return NAME;
}