BluetoothPbap.java revision 6f6c54519a9b15379bb79e195655b6bd4fc5967a
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; 736f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta private BluetoothAdapter mAdapter; 743f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 753f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** There was an error trying to obtain the state */ 763f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public static final int STATE_ERROR = -1; 77bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly /** No client currently connected */ 783f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public static final int STATE_DISCONNECTED = 0; 793f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** Connection attempt in progress */ 803f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public static final int STATE_CONNECTING = 1; 81bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly /** Client is currently connected */ 823f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public static final int STATE_CONNECTED = 2; 833f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 843f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public static final int RESULT_FAILURE = 0; 853f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public static final int RESULT_SUCCESS = 1; 863f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** Connection canceled before completion. */ 873f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public static final int RESULT_CANCELED = 2; 883f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 893f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 903f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * An interface for notifying Bluetooth PCE IPC clients when they have 91c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan * been connected to the BluetoothPbap service. 923f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 933f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public interface ServiceListener { 943f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 953f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Called to notify the client when this proxy object has been 963f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * connected to the BluetoothPbap service. Clients must wait for 973f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * this callback before making IPC calls on the BluetoothPbap 983f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * service. 993f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 1006f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta public void onServiceConnected(BluetoothPbap proxy); 1013f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 1023f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 1033f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Called to notify the client that this proxy object has been 1043f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * disconnected from the BluetoothPbap service. Clients must not 1053f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * make IPC calls on the BluetoothPbap service after this callback. 1063f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * This callback will currently only occur if the application hosting 1073f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * the BluetoothPbap service, but may be called more often in future. 1083f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 1093f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public void onServiceDisconnected(); 1103f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 1113f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 1126f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 1136f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta new IBluetoothStateChangeCallback.Stub() { 1146f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta public void onBluetoothStateChange(boolean up) { 1156f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); 1166f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (!up) { 1176f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (DBG) Log.d(TAG,"Unbinding service..."); 1186f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta synchronized (mConnection) { 1196f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta try { 1206f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mService = null; 1216f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mContext.unbindService(mConnection); 1226f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } catch (Exception re) { 1236f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta Log.e(TAG,"",re); 1246f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1256f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1266f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } else { 1276f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta synchronized (mConnection) { 1286f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta try { 1296f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (mService == null) { 1306f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (DBG) Log.d(TAG,"Binding service..."); 1316f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (!mContext.bindService( 1326f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta new Intent(IBluetoothPbap.class.getName()), 1336f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mConnection, 0)) { 1346f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta Log.e(TAG, "Could not bind to Bluetooth PBAP Service"); 1356f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1366f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1376f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } catch (Exception re) { 1386f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta Log.e(TAG,"",re); 1396f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1406f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1416f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1426f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1436f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta }; 1446f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta 1453f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 146c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan * Create a BluetoothPbap proxy object. 1473f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 1483f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public BluetoothPbap(Context context, ServiceListener l) { 1493f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu mContext = context; 1503f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu mServiceListener = l; 1516f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mAdapter = BluetoothAdapter.getDefaultAdapter(); 1526f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta IBluetoothManager mgr = mAdapter.getBluetoothManager(); 1536f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (mgr != null) { 1546f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta try { 1556f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 1566f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } catch (RemoteException e) { 1576f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta Log.e(TAG,"",e); 1586f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1596f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1603f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (!context.bindService(new Intent(IBluetoothPbap.class.getName()), mConnection, 0)) { 1613f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu Log.e(TAG, "Could not bind to Bluetooth Pbap Service"); 1623f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 1633f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 1643f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 1653f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu protected void finalize() throws Throwable { 1663f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu try { 1673f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu close(); 1683f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } finally { 1693f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu super.finalize(); 1703f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 1713f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 1723f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 1733f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 1743f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Close the connection to the backing service. 175c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan * Other public functions of BluetoothPbap will return default error 1763f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * results once close() has been called. Multiple invocations of close() 1773f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * are ok. 1783f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 1793f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public synchronized void close() { 1806f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta IBluetoothManager mgr = mAdapter.getBluetoothManager(); 1816f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (mgr != null) { 1826f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta try { 1836f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 1846f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } catch (Exception e) { 1856f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta Log.e(TAG,"",e); 1866f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1876f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1886f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta 1896f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta synchronized (mConnection) { 1906f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta if (mService != null) { 1916f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta try { 1926f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mService = null; 1936f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mContext.unbindService(mConnection); 1946f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mConnection = null; 1956f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } catch (Exception re) { 1966f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta Log.e(TAG,"",re); 1976f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1986f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta } 1993f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2009bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh mServiceListener = null; 2013f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2023f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 2033f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 204c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan * Get the current state of the BluetoothPbap service. 2053f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * @return One of the STATE_ return codes, or STATE_ERROR if this proxy 206c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan * object is currently not connected to the Pbap service. 2073f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 2083f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public int getState() { 2093f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (DBG) log("getState()"); 2103f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (mService != null) { 2113f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu try { 2123f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu return mService.getState(); 2133f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } catch (RemoteException e) {Log.e(TAG, e.toString());} 2143f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } else { 2153f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu Log.w(TAG, "Proxy not attached to service"); 2163f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (DBG) log(Log.getStackTraceString(new Throwable())); 2173f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 218c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan return BluetoothPbap.STATE_ERROR; 2193f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2203f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 2213f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 222bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * Get the currently connected remote Bluetooth device (PCE). 223bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * @return The remote Bluetooth device, or null if not in connected or 224bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * connecting state, or if this proxy object is not connected to 225bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * the Pbap service. 2263f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 227bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly public BluetoothDevice getClient() { 228bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly if (DBG) log("getClient()"); 2293f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (mService != null) { 2303f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu try { 231bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly return mService.getClient(); 2323f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } catch (RemoteException e) {Log.e(TAG, e.toString());} 2333f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } else { 2343f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu Log.w(TAG, "Proxy not attached to service"); 2353f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (DBG) log(Log.getStackTraceString(new Throwable())); 2363f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2373f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu return null; 2383f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2393f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 2403f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 241bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * Returns true if the specified Bluetooth device is connected (does not 242bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * include connecting). Returns false if not connected, or if this proxy 243bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * object is not currently connected to the Pbap service. 2443f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 245bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly public boolean isConnected(BluetoothDevice device) { 246bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly if (DBG) log("isConnected(" + device + ")"); 2473f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (mService != null) { 2483f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu try { 249bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly return mService.isConnected(device); 2503f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } catch (RemoteException e) {Log.e(TAG, e.toString());} 2513f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } else { 2523f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu Log.w(TAG, "Proxy not attached to service"); 2533f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (DBG) log(Log.getStackTraceString(new Throwable())); 2543f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2553f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu return false; 2563f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2573f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 2583f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 259bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * Disconnects the current Pbap client (PCE). Currently this call blocks, 260f51eadaf1f83abfe16a609a4ded6d789494689b2Jake Hamby * it may soon be made asynchronous. Returns false if this proxy object is 261c8b04a93a619ba91997d7454865f0a71fb6ae981Jackson Fan * not currently connected to the Pbap service. 2623f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 263bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly public boolean disconnect() { 264bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly if (DBG) log("disconnect()"); 2653f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (mService != null) { 2663f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu try { 267bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly mService.disconnect(); 2683f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu return true; 2693f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } catch (RemoteException e) {Log.e(TAG, e.toString());} 2703f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } else { 2713f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu Log.w(TAG, "Proxy not attached to service"); 2723f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (DBG) log(Log.getStackTraceString(new Throwable())); 2733f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2743f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu return false; 2753f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2763f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 2773f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu /** 2783f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * Check class bits for possible PBAP support. 2793f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * This is a simple heuristic that tries to guess if a device with the 2803f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * given class bits might support PBAP. It is not accurate for all 2813f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * devices. It tries to err on the side of false positives. 2823f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu * @return True if this device might support PBAP. 2833f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu */ 284005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly public static boolean doesClassMatchSink(BluetoothClass btClass) { 2853f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu // TODO optimize the rule 286005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly switch (btClass.getDeviceClass()) { 2873f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu case BluetoothClass.Device.COMPUTER_DESKTOP: 2883f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu case BluetoothClass.Device.COMPUTER_LAPTOP: 2893f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu case BluetoothClass.Device.COMPUTER_SERVER: 2903f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu case BluetoothClass.Device.COMPUTER_UNCATEGORIZED: 2913f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu return true; 2923f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu default: 2933f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu return false; 2943f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2953f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 2963f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 2973f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu private ServiceConnection mConnection = new ServiceConnection() { 2983f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public void onServiceConnected(ComponentName className, IBinder service) { 2993f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (DBG) log("Proxy object connected"); 3003f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu mService = IBluetoothPbap.Stub.asInterface(service); 3013f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (mServiceListener != null) { 3026f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta mServiceListener.onServiceConnected(BluetoothPbap.this); 3033f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 3043f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 3053f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu public void onServiceDisconnected(ComponentName className) { 3063f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (DBG) log("Proxy object disconnected"); 3073f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu mService = null; 3083f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu if (mServiceListener != null) { 3093f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu mServiceListener.onServiceDisconnected(); 3103f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 3113f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 3123f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu }; 3133f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu 3143f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu private static void log(String msg) { 3153f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu Log.d(TAG, msg); 3163f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu } 3173f41673265dcaaef058703311c5481e8a51fd8beJiafa Liu} 318