Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a01c31e authored by Joseph Pirozzo's avatar Joseph Pirozzo Committed by android-build-merger
Browse files

Merge "PBAP Multi Connection"

am: b8c54887

Change-Id: I72ed8c9bdbdcb939c2c0d442daff34f7c6c14018
parents ab92e5d0 b8c54887
Loading
Loading
Loading
Loading
+88 −21
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.bluetooth.pbapclient;
package com.android.bluetooth.pbapclient;


import android.accounts.Account;
import android.accounts.AccountManager;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.IBluetoothPbapClient;
import android.bluetooth.IBluetoothPbapClient;
@@ -23,15 +25,19 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.provider.CallLog;
import android.provider.Settings;
import android.provider.Settings;
import android.util.Log;
import android.util.Log;


import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.Utils;


import java.lang.IllegalArgumentException;
import java.lang.IllegalArgumentException;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.List;
import java.util.List;
import java.util.Map;


/**
/**
 * Provides Bluetooth Phone Book Access Profile Client profile.
 * Provides Bluetooth Phone Book Access Profile Client profile.
@@ -41,7 +47,10 @@ import java.util.List;
public class PbapClientService extends ProfileService {
public class PbapClientService extends ProfileService {
    private static final boolean DBG = false;
    private static final boolean DBG = false;
    private static final String TAG = "PbapClientService";
    private static final String TAG = "PbapClientService";
    private PbapClientStateMachine mPbapClientStateMachine;
    // MAXIMUM_DEVICES set to 10 to prevent an excessive number of simultaneous devices.
    private static final int MAXIMUM_DEVICES = 10;
    private Map<BluetoothDevice, PbapClientStateMachine> mPbapClientStateMachineMap =
            new ConcurrentHashMap<>();
    private static PbapClientService sPbapClientService;
    private static PbapClientService sPbapClientService;
    private PbapBroadcastReceiver mPbapBroadcastReceiver = new PbapBroadcastReceiver();
    private PbapBroadcastReceiver mPbapBroadcastReceiver = new PbapBroadcastReceiver();


@@ -67,9 +76,8 @@ public class PbapClientService extends ProfileService {
        } catch (Exception e) {
        } catch (Exception e) {
            Log.w(TAG,"Unable to register pbapclient receiver", e);
            Log.w(TAG,"Unable to register pbapclient receiver", e);
        }
        }
        mPbapClientStateMachine = new PbapClientStateMachine(this, this);
        removeUncleanAccounts();
        setPbapClientService(this);
        setPbapClientService(this);
        mPbapClientStateMachine.start();
        return true;
        return true;
    }
    }


@@ -80,18 +88,47 @@ public class PbapClientService extends ProfileService {
        } catch (Exception e) {
        } catch (Exception e) {
            Log.w(TAG,"Unable to unregister pbapclient receiver", e);
            Log.w(TAG,"Unable to unregister pbapclient receiver", e);
        }
        }
        if (mPbapClientStateMachine != null) {
        for (PbapClientStateMachine pbapClientStateMachine : mPbapClientStateMachineMap.values()) {
            mPbapClientStateMachine.doQuit();
            pbapClientStateMachine.doQuit();
        }
        }
        return true;
        return true;
    }
    }


    @Override
    @Override
    protected boolean cleanup() {
    protected boolean cleanup() {
        removeUncleanAccounts();
        clearPbapClientService();
        clearPbapClientService();
        return true;
        return true;
    }
    }


    void cleanupDevice(BluetoothDevice device) {
        Log.w(TAG, "Cleanup device: " + device);
        synchronized (mPbapClientStateMachineMap) {
            PbapClientStateMachine pbapClientStateMachine = mPbapClientStateMachineMap.get(device);
            if (pbapClientStateMachine != null) {
                mPbapClientStateMachineMap.remove(device);
            }
        }
    }

    private void removeUncleanAccounts() {
        // Find all accounts that match the type "pbap" and delete them.
        AccountManager accountManager = AccountManager.get(this);
        Account[] accounts =
                accountManager.getAccountsByType(getString(R.string.pbap_account_type));
        Log.w(TAG, "Found " + accounts.length + " unclean accounts");
        for (Account acc : accounts) {
            Log.w(TAG, "Deleting " + acc);
            // The device ID is the name of the account.
            accountManager.removeAccountExplicitly(acc);
        }
        try {
            getContentResolver().delete(CallLog.Calls.CONTENT_URI, null, null);
        } catch (IllegalArgumentException e) {
            Log.w(TAG, "Call Logs could not be deleted, they may not exist yet.");
        }
    }

    private class PbapBroadcastReceiver extends BroadcastReceiver {
    private class PbapBroadcastReceiver extends BroadcastReceiver {
        @Override
        @Override
        public void onReceive(Context context, Intent intent) {
        public void onReceive(Context context, Intent intent) {
@@ -103,7 +140,9 @@ public class PbapClientService extends ProfileService {
                    disconnect(device);
                    disconnect(device);
                }
                }
            } else if(action.equals(Intent.ACTION_USER_UNLOCKED)) {
            } else if(action.equals(Intent.ACTION_USER_UNLOCKED)) {
                mPbapClientStateMachine.resumeDownload();
                for (PbapClientStateMachine stateMachine : mPbapClientStateMachineMap.values()) {
                    stateMachine.resumeDownload();
                }
            }
            }
        }
        }
    }
    }
@@ -225,7 +264,7 @@ public class PbapClientService extends ProfileService {
    private static synchronized void setPbapClientService(PbapClientService instance) {
    private static synchronized void setPbapClientService(PbapClientService instance) {
        if (instance != null && instance.isAvailable()) {
        if (instance != null && instance.isAvailable()) {
            if (DBG) {
            if (DBG) {
                Log.d(TAG, "setPbapClientService(): set to: " + sPbapClientService);
                Log.d(TAG, "setPbapClientService(): previously set to: " + sPbapClientService);
            }
            }
            sPbapClientService = instance;
            sPbapClientService = instance;
        } else {
        } else {
@@ -247,24 +286,36 @@ public class PbapClientService extends ProfileService {
        if (device == null) throw new IllegalArgumentException("Null device");
        if (device == null) throw new IllegalArgumentException("Null device");
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        Log.d(TAG,"Received request to ConnectPBAPPhonebook " + device.getAddress());
        Log.d(TAG,"Received request to ConnectPBAPPhonebook " + device.getAddress());
        int connectionState = mPbapClientStateMachine.getConnectionState();
        if (getPriority(device) <= BluetoothProfile.PRIORITY_OFF) {
        if (connectionState == BluetoothProfile.STATE_CONNECTED ||
                connectionState == BluetoothProfile.STATE_CONNECTING) {
            Log.w(TAG,"Received connect request while already connecting/connected.");
            return false;
            return false;
        }
        }
        if (getPriority(device) > BluetoothProfile.PRIORITY_OFF) {
        synchronized (mPbapClientStateMachineMap) {
            mPbapClientStateMachine.connect(device);
            PbapClientStateMachine pbapClientStateMachine = mPbapClientStateMachineMap.get(device);
            if (pbapClientStateMachine == null
                    && mPbapClientStateMachineMap.size() < MAXIMUM_DEVICES) {
                pbapClientStateMachine = new PbapClientStateMachine(this, device);
                pbapClientStateMachine.start();
                mPbapClientStateMachineMap.put(device, pbapClientStateMachine);
                return true;
                return true;
        }
            } else {
                Log.w(TAG, "Received connect request while already connecting/connected.");
                return false;
                return false;
            }
            }
        }
    }


    boolean disconnect(BluetoothDevice device) {
    boolean disconnect(BluetoothDevice device) {
        if (device == null) throw new IllegalArgumentException("Null device");
        if (device == null) throw new IllegalArgumentException("Null device");
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        mPbapClientStateMachine.disconnect(device);
        PbapClientStateMachine pbapClientStateMachine = mPbapClientStateMachineMap.get(device);
        if (pbapClientStateMachine != null) {
            pbapClientStateMachine.disconnect(device);
            return true;
            return true;

        } else {
            Log.w(TAG, "disconnect() called on unconnected device.");
            return false;
        }
    }
    }


    public List<BluetoothDevice> getConnectedDevices() {
    public List<BluetoothDevice> getConnectedDevices() {
@@ -275,13 +326,29 @@ public class PbapClientService extends ProfileService {


    private List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
    private List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        return mPbapClientStateMachine.getDevicesMatchingConnectionStates(states);
        List<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>(0);
        for (Map.Entry<BluetoothDevice, PbapClientStateMachine> stateMachineEntry :
                mPbapClientStateMachineMap.entrySet()) {
            int currentDeviceState = stateMachineEntry.getValue().getConnectionState();
            for (int state : states) {
                if (currentDeviceState == state) {
                    deviceList.add(stateMachineEntry.getKey());
                    break;
                }
            }
        }
        return deviceList;
    }
    }


    int getConnectionState(BluetoothDevice device) {
    int getConnectionState(BluetoothDevice device) {
        if (device == null) throw new IllegalArgumentException("Null device");
        if (device == null) throw new IllegalArgumentException("Null device");
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        return mPbapClientStateMachine.getConnectionState(device);
        PbapClientStateMachine pbapClientStateMachine = mPbapClientStateMachineMap.get(device);
        if (pbapClientStateMachine == null) {
            return BluetoothProfile.STATE_DISCONNECTED;
        } else {
            return pbapClientStateMachine.getConnectionState(device);
        }
    }
    }


    public boolean setPriority(BluetoothDevice device, int priority) {
    public boolean setPriority(BluetoothDevice device, int priority) {
@@ -308,8 +375,8 @@ public class PbapClientService extends ProfileService {
    @Override
    @Override
    public void dump(StringBuilder sb) {
    public void dump(StringBuilder sb) {
        super.dump(sb);
        super.dump(sb);
        if (mPbapClientStateMachine != null) {
        for (PbapClientStateMachine stateMachine : mPbapClientStateMachineMap.values()) {
            mPbapClientStateMachine.dump(sb);
            stateMachine.dump(sb);
        }
        }
    }
    }
}
}
+24 −100
Original line number Original line Diff line number Diff line
@@ -41,8 +41,6 @@
 */
 */
package com.android.bluetooth.pbapclient;
package com.android.bluetooth.pbapclient;


import android.accounts.Account;
import android.accounts.AccountManager;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothPbapClient;
import android.bluetooth.BluetoothPbapClient;
@@ -56,7 +54,6 @@ import android.os.Message;
import android.os.ParcelUuid;
import android.os.ParcelUuid;
import android.os.Process;
import android.os.Process;
import android.os.UserManager;
import android.os.UserManager;
import android.provider.CallLog;
import android.util.Log;
import android.util.Log;


import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ProfileService;
@@ -65,7 +62,6 @@ import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.util.StateMachine;


import java.lang.IllegalStateException;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;


@@ -74,7 +70,6 @@ final class PbapClientStateMachine extends StateMachine {
    private static final String TAG = "PbapClientStateMachine";
    private static final String TAG = "PbapClientStateMachine";


    // Messages for handling connect/disconnect requests.
    // Messages for handling connect/disconnect requests.
    private static final int MSG_CONNECT = 1;
    private static final int MSG_DISCONNECT = 2;
    private static final int MSG_DISCONNECT = 2;
    private static final int MSG_SDP_COMPLETE = 9;
    private static final int MSG_SDP_COMPLETE = 9;


@@ -98,9 +93,8 @@ final class PbapClientStateMachine extends StateMachine {
    private State mDisconnecting;
    private State mDisconnecting;


    // mCurrentDevice may only be changed in Disconnected State.
    // mCurrentDevice may only be changed in Disconnected State.
    private BluetoothDevice mCurrentDevice = null;
    private final BluetoothDevice mCurrentDevice;
    private PbapClientService mService;
    private PbapClientService mService;
    private Context mContext;
    private PbapClientConnectionHandler mConnectionHandler;
    private PbapClientConnectionHandler mConnectionHandler;
    private HandlerThread mHandlerThread = null;
    private HandlerThread mHandlerThread = null;
    private UserManager mUserManager = null;
    private UserManager mUserManager = null;
@@ -108,25 +102,24 @@ final class PbapClientStateMachine extends StateMachine {
    // mMostRecentState maintains previous state for broadcasting transitions.
    // mMostRecentState maintains previous state for broadcasting transitions.
    private int mMostRecentState = BluetoothProfile.STATE_DISCONNECTED;
    private int mMostRecentState = BluetoothProfile.STATE_DISCONNECTED;


    PbapClientStateMachine(PbapClientService svc, Context context) {
    PbapClientStateMachine(PbapClientService svc, BluetoothDevice device) {
        super(TAG);
        super(TAG);


        mService = svc;
        mService = svc;
        mContext = context;
        mCurrentDevice = device;
        mLock = new Object();
        mLock = new Object();
        mUserManager = UserManager.get(mContext);
        mUserManager = UserManager.get(mService);
        mDisconnected = new Disconnected();
        mDisconnected = new Disconnected();
        mConnecting = new Connecting();
        mConnecting = new Connecting();
        mDisconnecting = new Disconnecting();
        mDisconnecting = new Disconnecting();
        mConnected = new Connected();
        mConnected = new Connected();
        removeUncleanAccounts();


        addState(mDisconnected);
        addState(mDisconnected);
        addState(mConnecting);
        addState(mConnecting);
        addState(mDisconnecting);
        addState(mDisconnecting);
        addState(mConnected);
        addState(mConnected);


        setInitialState(mDisconnected);
        setInitialState(mConnecting);
    }
    }


    class Disconnected extends State {
    class Disconnected extends State {
@@ -136,44 +129,7 @@ final class PbapClientStateMachine extends StateMachine {
            onConnectionStateChanged(mCurrentDevice, mMostRecentState,
            onConnectionStateChanged(mCurrentDevice, mMostRecentState,
                    BluetoothProfile.STATE_DISCONNECTED);
                    BluetoothProfile.STATE_DISCONNECTED);
            mMostRecentState = BluetoothProfile.STATE_DISCONNECTED;
            mMostRecentState = BluetoothProfile.STATE_DISCONNECTED;
            synchronized (mLock) {
            quit();
                mCurrentDevice = null;
            }

        }

        @Override
        public boolean processMessage(Message message) {
            if (DBG) Log.d(TAG, "Processing MSG " + message.what + " from " + this.getName());
            switch (message.what) {
                case MSG_CONNECT:
                    if (message.obj instanceof BluetoothDevice) {
                        synchronized (mLock) {
                            mCurrentDevice = (BluetoothDevice) message.obj;
                        }
                        transitionTo(mConnecting);
                    } else {
                        Log.w(TAG, "Received CONNECT without valid device");
                        throw new IllegalStateException("invalid device");
                    }
                    break;

                case MSG_DISCONNECT:
                    Log.w(TAG, "Received unexpected disconnect while disconnected.");
                    // It is possible if something crashed for others to think we are connected
                    // already, just remind them.
                    if (message.obj instanceof BluetoothDevice) {
                        onConnectionStateChanged((BluetoothDevice) message.obj,
                                BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_DISCONNECTED);
                    }
                    break;

                default:
                    Log.w(TAG, "Received unexpected message while disconnected.");
                    return NOT_HANDLED;
            }
            return HANDLED;
        }
        }
    }
    }


@@ -197,9 +153,10 @@ final class PbapClientStateMachine extends StateMachine {
            mHandlerThread.start();
            mHandlerThread.start();
            mConnectionHandler = new PbapClientConnectionHandler.Builder()
            mConnectionHandler = new PbapClientConnectionHandler.Builder()
                                         .setLooper(mHandlerThread.getLooper())
                                         .setLooper(mHandlerThread.getLooper())
                    .setContext(mContext)
                                         .setContext(mService)
                                         .setClientSM(PbapClientStateMachine.this)
                                         .setClientSM(PbapClientStateMachine.this)
                    .setRemoteDevice(mCurrentDevice).build();
                                         .setRemoteDevice(mCurrentDevice)
                                         .build();


            sendMessageDelayed(MSG_CONNECT_TIMEOUT, CONNECT_TIMEOUT);
            sendMessageDelayed(MSG_CONNECT_TIMEOUT, CONNECT_TIMEOUT);
        }
        }
@@ -209,8 +166,8 @@ final class PbapClientStateMachine extends StateMachine {
            if (DBG) Log.d(TAG, "Processing MSG " + message.what + " from " + this.getName());
            if (DBG) Log.d(TAG, "Processing MSG " + message.what + " from " + this.getName());
            switch (message.what) {
            switch (message.what) {
                case MSG_DISCONNECT:
                case MSG_DISCONNECT:
                    if (message.obj instanceof BluetoothDevice &&
                    if (message.obj instanceof BluetoothDevice
                            ((BluetoothDevice) message.obj).equals(mCurrentDevice)) {
                            && message.obj.equals(mCurrentDevice)) {
                        removeMessages(MSG_CONNECT_TIMEOUT);
                        removeMessages(MSG_CONNECT_TIMEOUT);
                        transitionTo(mDisconnecting);
                        transitionTo(mDisconnecting);
                    }
                    }
@@ -227,10 +184,6 @@ final class PbapClientStateMachine extends StateMachine {
                    transitionTo(mDisconnecting);
                    transitionTo(mDisconnecting);
                    break;
                    break;


                case MSG_CONNECT:
                    Log.w(TAG, "Connecting already in progress");
                    break;

                case MSG_SDP_COMPLETE:
                case MSG_SDP_COMPLETE:
                    mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_CONNECT,
                    mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_CONNECT,
                            message.obj).sendToTarget();
                            message.obj).sendToTarget();
@@ -275,11 +228,11 @@ final class PbapClientStateMachine extends StateMachine {
            public void register() {
            public void register() {
                IntentFilter filter = new IntentFilter();
                IntentFilter filter = new IntentFilter();
                filter.addAction(BluetoothDevice.ACTION_SDP_RECORD);
                filter.addAction(BluetoothDevice.ACTION_SDP_RECORD);
                mContext.registerReceiver(this, filter);
                mService.registerReceiver(this, filter);
            }
            }


            public void unregister() {
            public void unregister() {
                mContext.unregisterReceiver(this);
                mService.unregisterReceiver(this);
            }
            }
        }
        }
    }
    }
@@ -306,7 +259,6 @@ final class PbapClientStateMachine extends StateMachine {
                    transitionTo(mDisconnected);
                    transitionTo(mDisconnected);
                    break;
                    break;


                case MSG_CONNECT:
                case MSG_DISCONNECT:
                case MSG_DISCONNECT:
                    deferMessage(message);
                    deferMessage(message);
                    break;
                    break;
@@ -345,14 +297,6 @@ final class PbapClientStateMachine extends StateMachine {
        public boolean processMessage(Message message) {
        public boolean processMessage(Message message) {
            if (DBG) Log.d(TAG, "Processing MSG " + message.what + " from " + this.getName());
            if (DBG) Log.d(TAG, "Processing MSG " + message.what + " from " + this.getName());
            switch (message.what) {
            switch (message.what) {
                case MSG_CONNECT:
                    onConnectionStateChanged(mCurrentDevice, BluetoothProfile.STATE_CONNECTED,
                            BluetoothProfile.STATE_CONNECTED);


                    Log.w(TAG, "Received CONNECT while Connected, ignoring");
                    break;

                case MSG_DISCONNECT:
                case MSG_DISCONNECT:
                    if ((message.obj instanceof BluetoothDevice) &&
                    if ((message.obj instanceof BluetoothDevice) &&
                            ((BluetoothDevice) message.obj).equals(mCurrentDevice)) {
                            ((BluetoothDevice) message.obj).equals(mCurrentDevice)) {
@@ -384,34 +328,32 @@ final class PbapClientStateMachine extends StateMachine {
        intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
        mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
        mService.notifyProfileConnectionStateChanged(device, BluetoothProfile.PBAP_CLIENT, state,
        mService.notifyProfileConnectionStateChanged(device, BluetoothProfile.PBAP_CLIENT, state,
                prevState);
                prevState);
    }
    }


    public void connect(BluetoothDevice device) {
        Log.d(TAG, "Connect Request " + device.getAddress());
        sendMessage(MSG_CONNECT, device);
    }

    public void disconnect(BluetoothDevice device) {
    public void disconnect(BluetoothDevice device) {
        Log.d(TAG, "Disconnect Request " + device);
        Log.d(TAG, "Disconnect Request " + device);
        sendMessage(MSG_DISCONNECT, device);
        sendMessage(MSG_DISCONNECT, device);
    }
    }


    public void resumeDownload() {
    public void resumeDownload() {
        removeUncleanAccounts();
        sendMessage(MSG_RESUME_DOWNLOAD);
        sendMessage(MSG_RESUME_DOWNLOAD);
    }
    }


    void doQuit() {
    void doQuit() {
        removeUncleanAccounts();
        if (mHandlerThread != null) {
        if (mHandlerThread != null) {
            mHandlerThread.quitSafely();
            mHandlerThread.quitSafely();
        }
        }
        quitNow();
        quitNow();
    }
    }


    @Override
    protected void onQuitting() {
        mService.cleanupDevice(mCurrentDevice);
    }

    public int getConnectionState() {
    public int getConnectionState() {
        IState currentState = getCurrentState();
        IState currentState = getCurrentState();
        if (currentState instanceof Disconnected) {
        if (currentState instanceof Disconnected) {
@@ -428,8 +370,8 @@ final class PbapClientStateMachine extends StateMachine {
    }
    }


    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
        int clientState = -1;
        int clientState;
        BluetoothDevice currentDevice = null;
        BluetoothDevice currentDevice;
        synchronized (mLock) {
        synchronized (mLock) {
            clientState = getConnectionState();
            clientState = getConnectionState();
            currentDevice = getDevice();
            currentDevice = getDevice();
@@ -472,25 +414,7 @@ final class PbapClientStateMachine extends StateMachine {
    }
    }


    Context getContext() {
    Context getContext() {
        return mContext;
        return mService;
    }

    private void removeUncleanAccounts() {
        // Find all accounts that match the type "pbap" and delete them.
        AccountManager accountManager = AccountManager.get(mContext);
        Account[] accounts = accountManager.getAccountsByType(
                mContext.getString(R.string.pbap_account_type));
        Log.w(TAG, "Found " + accounts.length + " unclean accounts");
        for (Account acc : accounts) {
            Log.w(TAG, "Deleting " + acc);
            // The device ID is the name of the account.
            accountManager.removeAccountExplicitly(acc);
        }
        try {
            mContext.getContentResolver().delete(CallLog.Calls.CONTENT_URI, null, null);
        } catch (IllegalArgumentException e) {
            // CallLogs could not be deleted, they may not exist yet.
        }
    }
    }


    public void dump(StringBuilder sb) {
    public void dump(StringBuilder sb) {