1cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo/* 2cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Copyright (C) 2016 The Android Open Source Project 3cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * 4cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Licensed under the Apache License, Version 2.0 (the "License"); 5cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * you may not use this file except in compliance with the License. 6cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * You may obtain a copy of the License at 7cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * 8cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * http://www.apache.org/licenses/LICENSE-2.0 9cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * 10cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Unless required by applicable law or agreed to in writing, software 11cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * distributed under the License is distributed on an "AS IS" BASIS, 12cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * See the License for the specific language governing permissions and 14cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * limitations under the License. 15cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 16cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 17cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzopackage android.bluetooth; 18cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 19cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport java.util.List; 20cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport java.util.ArrayList; 21cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport android.content.ComponentName; 22cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport android.content.Context; 23cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport android.content.Intent; 24cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport android.content.ServiceConnection; 25cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport android.os.RemoteException; 260a17db1cc5942ea000ca87bb72853de57a15ec64Jeff Sharkeyimport android.os.Binder; 27cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport android.os.IBinder; 28cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzoimport android.util.Log; 29cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 30cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo/** 31cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * This class provides the APIs to control the Bluetooth PBAP Client Profile. 32cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo *@hide 33cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 34cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzopublic final class BluetoothPbapClient implements BluetoothProfile { 35cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 36cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private static final String TAG = "BluetoothPbapClient"; 37cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private static final boolean DBG = false; 38cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private static final boolean VDBG = false; 39cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 40cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public static final String ACTION_CONNECTION_STATE_CHANGED = 41cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED"; 42cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 43cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private IBluetoothPbapClient mService; 44cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private final Context mContext; 45cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private ServiceListener mServiceListener; 46cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private BluetoothAdapter mAdapter; 47cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 48cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** There was an error trying to obtain the state */ 49cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public static final int STATE_ERROR = -1; 50cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 51cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public static final int RESULT_FAILURE = 0; 52cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public static final int RESULT_SUCCESS = 1; 53cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** Connection canceled before completion. */ 54cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public static final int RESULT_CANCELED = 2; 55cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 56cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 57cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo new IBluetoothStateChangeCallback.Stub() { 58cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public void onBluetoothStateChange(boolean up) { 59cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 60cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.d(TAG, "onBluetoothStateChange: PBAP CLIENT up=" + up); 61cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 62cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (!up) { 63cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (VDBG) { 64cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.d(TAG,"Unbinding service..."); 65cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 66cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo synchronized (mConnection) { 67cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 68cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mService = null; 69cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mContext.unbindService(mConnection); 70cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (Exception re) { 71cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG,"",re); 72cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 73cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 74cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } else { 75cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo synchronized (mConnection) { 76cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 77cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService == null) { 78cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (VDBG) { 79cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.d(TAG,"Binding service..."); 80cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 81cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo doBind(); 82cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 83cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (Exception re) { 84cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG,"",re); 85cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 86cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 87cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 88cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 89cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo }; 90cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 91cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** 92cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Create a BluetoothPbapClient proxy object. 93cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 94cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo BluetoothPbapClient(Context context, ServiceListener l) { 95cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 96cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.d(TAG, "Create BluetoothPbapClient proxy object"); 97cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 98cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mContext = context; 99cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mServiceListener = l; 100cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mAdapter = BluetoothAdapter.getDefaultAdapter(); 101cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo IBluetoothManager mgr = mAdapter.getBluetoothManager(); 102cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mgr != null) { 103cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 104cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 105cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (RemoteException e) { 106cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG,"",e); 107cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 108cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 109cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo doBind(); 110cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 111cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 112cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private boolean doBind() { 113cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Intent intent = new Intent(IBluetoothPbapClient.class.getName()); 114cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 115cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo intent.setComponent(comp); 116cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, 117cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo android.os.Process.myUserHandle())) { 118cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG, "Could not bind to Bluetooth PBAP Client Service with " + intent); 119cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return false; 120cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 121cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return true; 122cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 123cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 124cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo protected void finalize() throws Throwable { 125cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 126cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo close(); 127cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } finally { 128cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo super.finalize(); 129cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 130cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 131cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 132cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** 133cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Close the connection to the backing service. 134cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Other public functions of BluetoothPbapClient will return default error 135cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * results once close() has been called. Multiple invocations of close() 136cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * are ok. 137cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 138cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public synchronized void close() { 139cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo IBluetoothManager mgr = mAdapter.getBluetoothManager(); 140cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mgr != null) { 141cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 142cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 143cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (Exception e) { 144cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG,"",e); 145cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 146cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 147cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 148cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo synchronized (mConnection) { 149cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService != null) { 150cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 151cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mService = null; 152cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mContext.unbindService(mConnection); 153cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (Exception re) { 154cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG,"",re); 155cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 156cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 157cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 158cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mServiceListener = null; 159cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 160cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 161cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** 162cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Initiate connection. 163cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Upon successful connection to remote PBAP server the Client will 164cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * attempt to automatically download the users phonebook and call log. 165cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * 166cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * @param device a remote device we want connect to 167cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * @return <code>true</code> if command has been issued successfully; 168cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * <code>false</code> otherwise; 169cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 170cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public boolean connect(BluetoothDevice device) { 171cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 172cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo log("connect(" + device + ") for PBAP Client."); 173cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 174cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService != null && isEnabled() && isValidDevice(device)) { 175cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 176cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return mService.connect(device); 177cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (RemoteException e) { 178cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG, Log.getStackTraceString(new Throwable())); 179cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return false; 180cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 181cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 182cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService == null) { 183cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.w(TAG, "Proxy not attached to service"); 184cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 185cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return false; 186cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 187cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 188cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** 189cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Initiate disconnect. 190cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * 191cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * @param device Remote Bluetooth Device 192cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * @return false on error, 193cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * true otherwise 194cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 195563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo public boolean disconnect(BluetoothDevice device) { 196cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 197563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo log("disconnect(" + device + ")" + new Exception() ); 198cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 199563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (mService != null && isEnabled() && isValidDevice(device)) { 200cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 201563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo mService.disconnect(device); 202cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return true; 203cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (RemoteException e) { 204cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG, Log.getStackTraceString(new Throwable())); 205cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return false; 206cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 207cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 208cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService == null) { 209cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.w(TAG, "Proxy not attached to service"); 210cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 211cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return false; 212cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 213cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 214cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** 215cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Get the list of connected devices. 216cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Currently at most one. 217cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * 218cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * @return list of connected devices 219cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 220cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo @Override 221cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public List<BluetoothDevice> getConnectedDevices() { 222cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 223cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo log("getConnectedDevices()"); 224cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 225cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService != null && isEnabled()) { 226cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 227cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return mService.getConnectedDevices(); 228cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (RemoteException e) { 229cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG, Log.getStackTraceString(new Throwable())); 230cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return new ArrayList<BluetoothDevice>(); 231cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 232cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 233cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService == null) { 234cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.w(TAG, "Proxy not attached to service"); 235cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 236cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return new ArrayList<BluetoothDevice>(); 237cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 238cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 239cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** 240cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Get the list of devices matching specified states. Currently at most one. 241cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * 242cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * @return list of matching devices 243cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 244cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo @Override 245cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 246cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 247cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo log("getDevicesMatchingStates()"); 248cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 249cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService != null && isEnabled()) { 250cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 251cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return mService.getDevicesMatchingConnectionStates(states); 252cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (RemoteException e) { 253cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG, Log.getStackTraceString(new Throwable())); 254cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return new ArrayList<BluetoothDevice>(); 255cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 256cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 257cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService == null) { 258cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.w(TAG, "Proxy not attached to service"); 259cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 260cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return new ArrayList<BluetoothDevice>(); 261cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 262cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 263cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo /** 264cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * Get connection state of device 265cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * 266cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo * @return device connection state 267cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo */ 268cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo @Override 269cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public int getConnectionState(BluetoothDevice device) { 270cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 271cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo log("getConnectionState(" + device + ")"); 272cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 273cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService != null && isEnabled() && isValidDevice(device)) { 274cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo try { 275cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return mService.getConnectionState(device); 276cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } catch (RemoteException e) { 277cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.e(TAG, Log.getStackTraceString(new Throwable())); 278cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return BluetoothProfile.STATE_DISCONNECTED; 279cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 280cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 281cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mService == null) { 282cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.w(TAG, "Proxy not attached to service"); 283cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 284cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return BluetoothProfile.STATE_DISCONNECTED; 285cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 286cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 287cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private final ServiceConnection mConnection = new ServiceConnection() { 288cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public void onServiceConnected(ComponentName className, IBinder service) { 289cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 290cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo log("Proxy object connected"); 291cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 2920a17db1cc5942ea000ca87bb72853de57a15ec64Jeff Sharkey mService = IBluetoothPbapClient.Stub.asInterface(Binder.allowBlocking(service)); 293cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mServiceListener != null) { 294cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT, BluetoothPbapClient.this); 295cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 296cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 297cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo public void onServiceDisconnected(ComponentName className) { 298cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (DBG) { 299cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo log("Proxy object disconnected"); 300cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 301cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mService = null; 302cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (mServiceListener != null) { 303cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo mServiceListener.onServiceDisconnected(BluetoothProfile.PBAP_CLIENT); 304cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 305cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 306cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo }; 307cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 308cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private static void log(String msg) { 309cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo Log.d(TAG, msg); 310cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 311cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 312cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private boolean isEnabled() { 313cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 314cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) { 315cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return true; 316cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 317cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo log("Bluetooth is Not enabled"); 318cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return false; 319cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 320cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo 321cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo private boolean isValidDevice(BluetoothDevice device) { 322cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (device == null) { 323cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return false; 324cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 325cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { 326cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return true; 327cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 328cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo return false; 329cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo } 330563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo 331563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo /** 332563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * Set priority of the profile 333563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * 334563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * <p> The device should already be paired. 335563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * Priority can be one of {@link #PRIORITY_ON} or 336563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * {@link #PRIORITY_OFF}, 337563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * 338563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * @param device Paired bluetooth device 339563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * @param priority 340563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * @return true if priority is set, false on error 341563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo */ 342563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo public boolean setPriority(BluetoothDevice device, int priority) { 343563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (DBG) { 344563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo log("setPriority(" + device + ", " + priority + ")"); 345563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 346563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (mService != null && isEnabled() && 347563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo isValidDevice(device)) { 348563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (priority != BluetoothProfile.PRIORITY_OFF && 349563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo priority != BluetoothProfile.PRIORITY_ON) { 350563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo return false; 351563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 352563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo try { 353563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo return mService.setPriority(device, priority); 354563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } catch (RemoteException e) { 355563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo Log.e(TAG, Log.getStackTraceString(new Throwable())); 356563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo return false; 357563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 358563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 359563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (mService == null) { 360563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo Log.w(TAG, "Proxy not attached to service"); 361563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 362563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo return false; 363563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 364563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo 365563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo /** 366563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * Get the priority of the profile. 367563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * 368563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * <p> The priority can be any of: 369563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, 370563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} 371563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * 372563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * @param device Bluetooth device 373563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo * @return priority of the device 374563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo */ 375563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo public int getPriority(BluetoothDevice device) { 376563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (VDBG) { 377563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo log("getPriority(" + device + ")"); 378563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 379563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (mService != null && isEnabled() && isValidDevice(device)) { 380563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo try { 381563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo return mService.getPriority(device); 382563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } catch (RemoteException e) { 383563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo Log.e(TAG, Log.getStackTraceString(new Throwable())); 384563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo return PRIORITY_OFF; 385563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 386563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 387563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (mService == null) { 388563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo Log.w(TAG, "Proxy not attached to service"); 389563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 390563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo return PRIORITY_OFF; 391563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 392cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo} 393