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