BluetoothPbap.java revision f76a50ce8fdc6aea22cabc77b2977a1a15a79630
13f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu/*
23f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Copyright (C) 2008 The Android Open Source Project
33f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *
43f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Licensed under the Apache License, Version 2.0 (the "License");
53f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * you may not use this file except in compliance with the License.
63f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * You may obtain a copy of the License at
73f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *
83f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *      http://www.apache.org/licenses/LICENSE-2.0
93f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *
103f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Unless required by applicable law or agreed to in writing, software
113f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * distributed under the License is distributed on an "AS IS" BASIS,
123f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * See the License for the specific language governing permissions and
143f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * limitations under the License.
153f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */
163f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
173f41673265dcaaef058703311c5481e8a51fd8beJiafa Liupackage android.bluetooth;
183f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
193f41673265dcaaef058703311c5481e8a51fd8beJiafa Liuimport android.content.ComponentName;
203f41673265dcaaef058703311c5481e8a51fd8beJiafa Liuimport android.content.Context;
213f41673265dcaaef058703311c5481e8a51fd8beJiafa Liuimport android.content.Intent;
223f41673265dcaaef058703311c5481e8a51fd8beJiafa Liuimport android.content.ServiceConnection;
233f41673265dcaaef058703311c5481e8a51fd8beJiafa Liuimport android.os.RemoteException;
243f41673265dcaaef058703311c5481e8a51fd8beJiafa Liuimport android.os.IBinder;
253f41673265dcaaef058703311c5481e8a51fd8beJiafa Liuimport android.os.ServiceManager;
263f41673265dcaaef058703311c5481e8a51fd8beJiafa Liuimport android.util.Log;
273f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
283f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu/**
293f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * The Android Bluetooth API is not finalized, and *will* change. Use at your
303f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * own risk.
313f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *
323f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Public API for controlling the Bluetooth Pbap Service. This includes
333f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Bluetooth Phone book Access profile.
343f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * BluetoothPbap is a proxy object for controlling the Bluetooth Pbap
353f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Service via IPC.
363f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *
373f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Creating a BluetoothPbap object will create a binding with the
383f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * BluetoothPbap service. Users of this object should call close() when they
393f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * are finished with the BluetoothPbap, so that this proxy object can unbind
403f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * from the service.
413f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *
423f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * This BluetoothPbap object is not immediately bound to the
433f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * BluetoothPbap service. Use the ServiceListener interface to obtain a
443f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * notification when it is bound, this is especially important if you wish to
453f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * immediately call methods on BluetoothPbap after construction.
463f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *
473f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Android only supports one connected Bluetooth Pce at a time.
483f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu *
493f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * @hide
503f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */
513f41673265dcaaef058703311c5481e8a51fd8beJiafa Liupublic class BluetoothPbap {
523f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
533f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    private static final String TAG = "BluetoothPbap";
543f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    private static final boolean DBG = false;
553f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
563f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /** int extra for PBAP_STATE_CHANGED_ACTION */
573f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final String PBAP_STATE =
583f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        "android.bluetooth.pbap.intent.PBAP_STATE";
593f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /** int extra for PBAP_STATE_CHANGED_ACTION */
603f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final String PBAP_PREVIOUS_STATE =
613f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        "android.bluetooth.pbap.intent.PBAP_PREVIOUS_STATE";
623f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
63f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa    /** Indicates the state of a pbap connection state has changed.
643f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     *  This intent will always contain PBAP_STATE, PBAP_PREVIOUS_STATE and
653f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     *  BluetoothIntent.ADDRESS extras.
663f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
673f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final String PBAP_STATE_CHANGED_ACTION =
683f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        "android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED";
693f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
703f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    private IBluetoothPbap mService;
713f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    private final Context mContext;
729bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh    private ServiceListener mServiceListener;
733f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
743f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /** There was an error trying to obtain the state */
753f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final int STATE_ERROR        = -1;
76bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    /** No client currently connected */
773f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final int STATE_DISCONNECTED = 0;
783f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /** Connection attempt in progress */
793f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final int STATE_CONNECTING   = 1;
80bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    /** Client is currently connected */
813f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final int STATE_CONNECTED    = 2;
823f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
833f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final int RESULT_FAILURE = 0;
843f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final int RESULT_SUCCESS = 1;
853f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /** Connection canceled before completion. */
863f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public static final int RESULT_CANCELED = 2;
873f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
883f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /**
893f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * An interface for notifying Bluetooth PCE IPC clients when they have
90c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan     * been connected to the BluetoothPbap service.
913f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
923f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public interface ServiceListener {
933f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        /**
943f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * Called to notify the client when this proxy object has been
953f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * connected to the BluetoothPbap service. Clients must wait for
963f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * this callback before making IPC calls on the BluetoothPbap
973f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * service.
983f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         */
993f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        public void onServiceConnected();
1003f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
1013f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        /**
1023f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * Called to notify the client that this proxy object has been
1033f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * disconnected from the BluetoothPbap service. Clients must not
1043f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * make IPC calls on the BluetoothPbap service after this callback.
1053f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * This callback will currently only occur if the application hosting
1063f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         * the BluetoothPbap service, but may be called more often in future.
1073f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu         */
1083f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        public void onServiceDisconnected();
1093f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
1103f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
1113f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /**
112c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan     * Create a BluetoothPbap proxy object.
1133f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
1143f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public BluetoothPbap(Context context, ServiceListener l) {
1153f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        mContext = context;
1163f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        mServiceListener = l;
1173f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        if (!context.bindService(new Intent(IBluetoothPbap.class.getName()), mConnection, 0)) {
1183f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            Log.e(TAG, "Could not bind to Bluetooth Pbap Service");
1193f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
1203f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
1213f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
1223f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    protected void finalize() throws Throwable {
1233f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        try {
1243f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            close();
1253f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        } finally {
1263f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            super.finalize();
1273f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
1283f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
1293f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
1303f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /**
1313f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * Close the connection to the backing service.
132c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan     * Other public functions of BluetoothPbap will return default error
1333f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * results once close() has been called. Multiple invocations of close()
1343f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * are ok.
1353f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
1363f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public synchronized void close() {
1373f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        if (mConnection != null) {
1383f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            mContext.unbindService(mConnection);
1393f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            mConnection = null;
1403f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
1419bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh        mServiceListener = null;
1423f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
1433f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
1443f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /**
145c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan     * Get the current state of the BluetoothPbap service.
1463f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * @return One of the STATE_ return codes, or STATE_ERROR if this proxy
147c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan     *         object is currently not connected to the Pbap service.
1483f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
1493f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    public int getState() {
1503f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        if (DBG) log("getState()");
1513f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        if (mService != null) {
1523f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            try {
1533f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu                return mService.getState();
1543f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            } catch (RemoteException e) {Log.e(TAG, e.toString());}
1553f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        } else {
1563f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            Log.w(TAG, "Proxy not attached to service");
1573f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            if (DBG) log(Log.getStackTraceString(new Throwable()));
1583f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
159c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan        return BluetoothPbap.STATE_ERROR;
1603f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
1613f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
1623f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /**
163bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Get the currently connected remote Bluetooth device (PCE).
164bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @return The remote Bluetooth device, or null if not in connected or
165bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     *         connecting state, or if this proxy object is not connected to
166bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     *         the Pbap service.
1673f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
168bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public BluetoothDevice getClient() {
169bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        if (DBG) log("getClient()");
1703f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        if (mService != null) {
1713f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            try {
172bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                return mService.getClient();
1733f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            } catch (RemoteException e) {Log.e(TAG, e.toString());}
1743f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        } else {
1753f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            Log.w(TAG, "Proxy not attached to service");
1763f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            if (DBG) log(Log.getStackTraceString(new Throwable()));
1773f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
1783f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        return null;
1793f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
1803f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
1813f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /**
182bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Returns true if the specified Bluetooth device is connected (does not
183bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * include connecting). Returns false if not connected, or if this proxy
184bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * object is not currently connected to the Pbap service.
1853f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
186bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean isConnected(BluetoothDevice device) {
187bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        if (DBG) log("isConnected(" + device + ")");
1883f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        if (mService != null) {
1893f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            try {
190bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                return mService.isConnected(device);
1913f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            } catch (RemoteException e) {Log.e(TAG, e.toString());}
1923f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        } else {
1933f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            Log.w(TAG, "Proxy not attached to service");
1943f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            if (DBG) log(Log.getStackTraceString(new Throwable()));
1953f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
1963f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        return false;
1973f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
1983f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
1993f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /**
200bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Disconnects the current Pbap client (PCE). Currently this call blocks,
201f51eadaf1f83abfe16a609a4ded6d789494689b2Jake Hamby     * it may soon be made asynchronous. Returns false if this proxy object is
202c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan     * not currently connected to the Pbap service.
2033f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
204bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean disconnect() {
205bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        if (DBG) log("disconnect()");
2063f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        if (mService != null) {
2073f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            try {
208bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                mService.disconnect();
2093f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu                return true;
2103f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            } catch (RemoteException e) {Log.e(TAG, e.toString());}
2113f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        } else {
2123f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            Log.w(TAG, "Proxy not attached to service");
2133f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            if (DBG) log(Log.getStackTraceString(new Throwable()));
2143f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
2153f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        return false;
2163f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
2173f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
2183f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    /**
2193f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * Check class bits for possible PBAP support.
2203f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * This is a simple heuristic that tries to guess if a device with the
2213f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * given class bits might support PBAP. It is not accurate for all
2223f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * devices. It tries to err on the side of false positives.
2233f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     * @return True if this device might support PBAP.
2243f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu     */
225005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static boolean doesClassMatchSink(BluetoothClass btClass) {
2263f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        // TODO optimize the rule
227005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly        switch (btClass.getDeviceClass()) {
2283f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        case BluetoothClass.Device.COMPUTER_DESKTOP:
2293f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        case BluetoothClass.Device.COMPUTER_LAPTOP:
2303f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        case BluetoothClass.Device.COMPUTER_SERVER:
2313f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
2323f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            return true;
2333f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        default:
2343f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            return false;
2353f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
2363f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
2373f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
2383f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    private ServiceConnection mConnection = new ServiceConnection() {
2393f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        public void onServiceConnected(ComponentName className, IBinder service) {
2403f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            if (DBG) log("Proxy object connected");
2413f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            mService = IBluetoothPbap.Stub.asInterface(service);
2423f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            if (mServiceListener != null) {
2433f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu                mServiceListener.onServiceConnected();
2443f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            }
2453f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
2463f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        public void onServiceDisconnected(ComponentName className) {
2473f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            if (DBG) log("Proxy object disconnected");
2483f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            mService = null;
2493f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            if (mServiceListener != null) {
2503f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu                mServiceListener.onServiceDisconnected();
2513f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu            }
2523f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        }
2533f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    };
2543f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu
2553f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    private static void log(String msg) {
2563f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu        Log.d(TAG, msg);
2573f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu    }
2583f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu}
259