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