12a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde/* 22a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Copyright (C) 2008 The Android Open Source Project 32a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 42a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Licensed under the Apache License, Version 2.0 (the "License"); 52a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * you may not use this file except in compliance with the License. 62a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * You may obtain a copy of the License at 72a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 82a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * http://www.apache.org/licenses/LICENSE-2.0 92a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 102a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Unless required by applicable law or agreed to in writing, software 112a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * distributed under the License is distributed on an "AS IS" BASIS, 122a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * See the License for the specific language governing permissions and 142a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * limitations under the License. 152a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 162a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 172a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondepackage android.bluetooth; 182a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 192a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport java.util.ArrayList; 202a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport java.util.List; 212a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 222a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport android.content.ComponentName; 232a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport android.content.Context; 242a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport android.content.Intent; 252a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport android.content.ServiceConnection; 262a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport android.os.RemoteException; 272a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport android.os.IBinder; 282a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport android.os.ServiceManager; 292a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondeimport android.util.Log; 302a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 31ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach/** 32ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * This class provides the APIs to control the Bluetooth SIM 33ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * Access Profile (SAP). 34ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * 35ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <p>BluetoothSap is a proxy object for controlling the Bluetooth 36ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 37ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * the BluetoothSap proxy object. 38ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * 39ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <p>Each method is protected with its appropriate permission. 40ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 41ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach */ 422a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bondepublic final class BluetoothSap implements BluetoothProfile { 432a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 442a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private static final String TAG = "BluetoothSap"; 452a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private static final boolean DBG = true; 462a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private static final boolean VDBG = false; 472a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 48ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach /** 49ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * Intent used to broadcast the change in connection state of the profile. 50ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * 51ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <p>This intent will have 4 extras: 52ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <ul> 53ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 54ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> 55ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 56ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * </ul> 57ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * 58ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 59ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 60ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 61ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * 62ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 63ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * receive. 64ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 65ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach */ 662a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public static final String ACTION_CONNECTION_STATE_CHANGED = 672a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde "android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED"; 682a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 692a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private IBluetoothSap mService; 702a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private final Context mContext; 712a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private ServiceListener mServiceListener; 722a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private BluetoothAdapter mAdapter; 732a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 74ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach /** 75ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * There was an error trying to obtain the state. 76ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 77ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach */ 78ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach public static final int STATE_ERROR = -1; 792a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 80ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach /** 81ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * Connection state change succceeded. 82ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 83ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach */ 842a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public static final int RESULT_SUCCESS = 1; 85ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach 86ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach /** 87ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * Connection canceled before completion. 88ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 89ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach */ 902a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public static final int RESULT_CANCELED = 2; 912a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 922a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 932a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde new IBluetoothStateChangeCallback.Stub() { 942a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public void onBluetoothStateChange(boolean up) { 952a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); 962a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (!up) { 972a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (VDBG) Log.d(TAG,"Unbinding service..."); 982a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde synchronized (mConnection) { 992a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 1002a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mService = null; 1012a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mContext.unbindService(mConnection); 1022a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (Exception re) { 1032a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG,"",re); 1042a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1052a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1062a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } else { 1072a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde synchronized (mConnection) { 1082a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 1092a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService == null) { 1102a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (VDBG) Log.d(TAG,"Binding service..."); 1112a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde doBind(); 1122a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1132a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (Exception re) { 1142a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG,"",re); 1152a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1162a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1172a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1182a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1192a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde }; 1202a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 1212a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 1222a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Create a BluetoothSap proxy object. 1232a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 1242a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /*package*/ BluetoothSap(Context context, ServiceListener l) { 1252a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) Log.d(TAG, "Create BluetoothSap proxy object"); 1262a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mContext = context; 1272a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mServiceListener = l; 1282a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mAdapter = BluetoothAdapter.getDefaultAdapter(); 1292a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde IBluetoothManager mgr = mAdapter.getBluetoothManager(); 1302a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mgr != null) { 1312a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 1322a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 1332a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) { 1342a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG,"",e); 1352a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1362a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1372a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde doBind(); 1382a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1392a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 1402a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde boolean doBind() { 141f308ab01dc9e7431b117cf034415495ad45621dbugo_yu Intent intent = new Intent(IBluetoothSap.class.getName()); 1422a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 1432a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde intent.setComponent(comp); 1442a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, 1452a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde android.os.Process.myUserHandle())) { 1462a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG, "Could not bind to Bluetooth SAP Service with " + intent); 1472a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 1482a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1492a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return true; 1502a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1512a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 1522a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde protected void finalize() throws Throwable { 1532a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 1542a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde close(); 1552a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } finally { 1562a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde super.finalize(); 1572a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1582a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1592a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 1602a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 1612a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Close the connection to the backing service. 1622a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Other public functions of BluetoothSap will return default error 1632a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * results once close() has been called. Multiple invocations of close() 1642a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * are ok. 165ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 1662a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 1672a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public synchronized void close() { 1682a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde IBluetoothManager mgr = mAdapter.getBluetoothManager(); 1692a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mgr != null) { 1702a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 1712a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 1722a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (Exception e) { 1732a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG,"",e); 1742a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1752a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1762a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 1772a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde synchronized (mConnection) { 1782a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null) { 1792a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 1802a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mService = null; 1812a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mContext.unbindService(mConnection); 1822a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (Exception re) { 1832a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG,"",re); 1842a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1852a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1862a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1872a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mServiceListener = null; 1882a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 1892a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 1902a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 1912a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Get the current state of the BluetoothSap service. 1922a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @return One of the STATE_ return codes, or STATE_ERROR if this proxy 1932a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * object is currently not connected to the Sap service. 194ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 1952a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 1962a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public int getState() { 1972a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (VDBG) log("getState()"); 1982a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null) { 1992a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 2002a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.getState(); 2012a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) {Log.e(TAG, e.toString());} 2022a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } else { 2032a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.w(TAG, "Proxy not attached to service"); 2042a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log(Log.getStackTraceString(new Throwable())); 2052a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2062a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return BluetoothSap.STATE_ERROR; 2072a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2082a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 2092a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 2102a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Get the currently connected remote Bluetooth device (PCE). 2112a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @return The remote Bluetooth device, or null if not in connected or 2122a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * connecting state, or if this proxy object is not connected to 2132a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * the Sap service. 214ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 2152a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 2162a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public BluetoothDevice getClient() { 2172a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (VDBG) log("getClient()"); 2182a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null) { 2192a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 2202a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.getClient(); 2212a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) {Log.e(TAG, e.toString());} 2222a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } else { 2232a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.w(TAG, "Proxy not attached to service"); 2242a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log(Log.getStackTraceString(new Throwable())); 2252a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2262a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return null; 2272a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2282a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 2292a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 2302a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Returns true if the specified Bluetooth device is connected. 2312a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Returns false if not connected, or if this proxy object is not 2322a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * currently connected to the Sap service. 233ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 2342a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 2352a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public boolean isConnected(BluetoothDevice device) { 2362a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (VDBG) log("isConnected(" + device + ")"); 2372a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null) { 2382a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 2392a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.isConnected(device); 2402a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) {Log.e(TAG, e.toString());} 2412a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } else { 2422a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.w(TAG, "Proxy not attached to service"); 2432a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log(Log.getStackTraceString(new Throwable())); 2442a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2452a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 2462a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2472a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 2482a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 2492a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Initiate connection. Initiation of outgoing connections is not 2502a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * supported for SAP server. 251ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 2522a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 2532a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public boolean connect(BluetoothDevice device) { 2542a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log("connect(" + device + ")" + "not supported for SAPS"); 2552a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 2562a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2572a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 2582a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 2592a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Initiate disconnect. 2602a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 2612a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @param device Remote Bluetooth Device 2622a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @return false on error, 2632a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * true otherwise 264ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 2652a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 2662a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public boolean disconnect(BluetoothDevice device) { 2672a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log("disconnect(" + device + ")"); 2682a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null && isEnabled() && 2692a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde isValidDevice(device)) { 2702a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 2712a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.disconnect(device); 2722a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) { 2732a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG, Log.getStackTraceString(new Throwable())); 2742a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 2752a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2762a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2772a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService == null) Log.w(TAG, "Proxy not attached to service"); 2782a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 2792a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2802a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 2812a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 2822a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Get the list of connected devices. Currently at most one. 2832a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 2842a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @return list of connected devices 285ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 2862a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 2872a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public List<BluetoothDevice> getConnectedDevices() { 2882a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log("getConnectedDevices()"); 2892a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null && isEnabled()) { 2902a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 2912a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.getConnectedDevices(); 2922a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) { 2932a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG, Log.getStackTraceString(new Throwable())); 2942a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return new ArrayList<BluetoothDevice>(); 2952a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2962a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 2972a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService == null) Log.w(TAG, "Proxy not attached to service"); 2982a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return new ArrayList<BluetoothDevice>(); 2992a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3002a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 3012a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 3022a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Get the list of devices matching specified states. Currently at most one. 3032a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 3042a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @return list of matching devices 305ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 3062a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 3072a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 3082a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log("getDevicesMatchingStates()"); 3092a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null && isEnabled()) { 3102a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 3112a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.getDevicesMatchingConnectionStates(states); 3122a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) { 3132a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG, Log.getStackTraceString(new Throwable())); 3142a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return new ArrayList<BluetoothDevice>(); 3152a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3162a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3172a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3182a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return new ArrayList<BluetoothDevice>(); 3192a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3202a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 3212a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 3222a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Get connection state of device 3232a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 3242a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @return device connection state 325ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 3262a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 3272a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public int getConnectionState(BluetoothDevice device) { 3282a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log("getConnectionState(" + device + ")"); 3292a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null && isEnabled() && 3302a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde isValidDevice(device)) { 3312a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 3322a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.getConnectionState(device); 3332a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) { 3342a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG, Log.getStackTraceString(new Throwable())); 3352a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return BluetoothProfile.STATE_DISCONNECTED; 3362a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3372a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3382a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3392a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return BluetoothProfile.STATE_DISCONNECTED; 3402a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3412a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 3422a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 3432a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Set priority of the profile 3442a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 3452a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * <p> The device should already be paired. 3462a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 3472a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @param device Paired bluetooth device 3482a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @param priority 3492a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @return true if priority is set, false on error 350ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 3512a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 3522a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public boolean setPriority(BluetoothDevice device, int priority) { 3532a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log("setPriority(" + device + ", " + priority + ")"); 3542a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null && isEnabled() && 3552a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde isValidDevice(device)) { 3562a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (priority != BluetoothProfile.PRIORITY_OFF && 3572a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde priority != BluetoothProfile.PRIORITY_ON) { 3582a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 3592a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3602a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 3612a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.setPriority(device, priority); 3622a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) { 3632a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG, Log.getStackTraceString(new Throwable())); 3642a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 3652a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3662a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3672a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3682a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 3692a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3702a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 3712a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde /** 3722a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * Get the priority of the profile. 3732a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * 3742a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @param device Bluetooth device 3752a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde * @return priority of the device 376ab2581398c812917145088590bd18eb83f3a2ea6Andre Eisenbach * @hide 3772a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde */ 3782a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public int getPriority(BluetoothDevice device) { 3792a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (VDBG) log("getPriority(" + device + ")"); 3802a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService != null && isEnabled() && 3812a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde isValidDevice(device)) { 3822a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde try { 3832a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return mService.getPriority(device); 3842a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } catch (RemoteException e) { 3852a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.e(TAG, Log.getStackTraceString(new Throwable())); 3862a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return PRIORITY_OFF; 3872a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3882a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3892a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3902a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return PRIORITY_OFF; 3912a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 3922a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 3932a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private ServiceConnection mConnection = new ServiceConnection() { 3942a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public void onServiceConnected(ComponentName className, IBinder service) { 3952a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log("Proxy object connected"); 3962a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mService = IBluetoothSap.Stub.asInterface(service); 3972a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mServiceListener != null) { 3982a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mServiceListener.onServiceConnected(BluetoothProfile.SAP, BluetoothSap.this); 3992a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 4002a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 4012a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde public void onServiceDisconnected(ComponentName className) { 4022a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (DBG) log("Proxy object disconnected"); 4032a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mService = null; 4042a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (mServiceListener != null) { 4052a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde mServiceListener.onServiceDisconnected(BluetoothProfile.SAP); 4062a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 4072a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 4082a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde }; 4092a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 4102a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private static void log(String msg) { 4112a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde Log.d(TAG, msg); 4122a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 4132a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 4142a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private boolean isEnabled() { 4152a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 4162a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 4172a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) 4182a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return true; 4192a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde log("Bluetooth is Not enabled"); 4202a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 4212a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 4222a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 4232a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde private boolean isValidDevice(BluetoothDevice device) { 4242a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (device == null) 4252a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 4262a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 4272a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) 4282a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return true; 4292a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde return false; 4302a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde } 4312a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde 4322a5f608e7a5765db3b91165dac5b6280b26da26cCasper Bonde} 433