BluetoothPbapClient.java revision cfa8a6469463ace9c3336e3686d950792a2c7ad4
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 BluetoothDevice mDevice;
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                mDevice = device;
177cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return mService.connect(device);
178cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            } catch (RemoteException e) {
179cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
180cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return false;
181cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
182cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
183cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService == null) {
184cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            Log.w(TAG, "Proxy not attached to service");
185cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
186cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        return false;
187cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    }
188cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo
189cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    /**
190cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * Initiate disconnect.
191cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     *
192cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * @param device Remote Bluetooth Device
193cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * @return false on error,
194cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     *               true otherwise
195cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     */
196cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    public boolean disconnect() {
197cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (DBG) {
198cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            log("disconnect(" + mDevice + ")");
199cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
200cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService != null && isEnabled() && isValidDevice(mDevice)) {
201cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            try {
202cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                mService.disconnect(mDevice);
203cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return true;
204cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            } catch (RemoteException e) {
205cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo              Log.e(TAG, Log.getStackTraceString(new Throwable()));
206cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo              return false;
207cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
208cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
209cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService == null) {
210cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            Log.w(TAG, "Proxy not attached to service");
211cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
212cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        return false;
213cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    }
214cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo
215cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    /**
216cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * Get the list of connected devices.
217cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * Currently at most one.
218cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     *
219cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * @return list of connected devices
220cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     */
221cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    @Override
222cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    public List<BluetoothDevice> getConnectedDevices() {
223cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (DBG) {
224cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            log("getConnectedDevices()");
225cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
226cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService != null && isEnabled()) {
227cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            try {
228cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return mService.getConnectedDevices();
229cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            } catch (RemoteException e) {
230cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
231cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return new ArrayList<BluetoothDevice>();
232cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
233cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
234cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService == null) {
235cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            Log.w(TAG, "Proxy not attached to service");
236cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
237cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        return new ArrayList<BluetoothDevice>();
238cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    }
239cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo
240cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    /**
241cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * Get the list of devices matching specified states. Currently at most one.
242cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     *
243cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * @return list of matching devices
244cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     */
245cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    @Override
246cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
247cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (DBG) {
248cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            log("getDevicesMatchingStates()");
249cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
250cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService != null && isEnabled()) {
251cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            try {
252cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return mService.getDevicesMatchingConnectionStates(states);
253cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            } catch (RemoteException e) {
254cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
255cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return new ArrayList<BluetoothDevice>();
256cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
257cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
258cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService == null) {
259cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            Log.w(TAG, "Proxy not attached to service");
260cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
261cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        return new ArrayList<BluetoothDevice>();
262cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    }
263cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo
264cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    /**
265cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * Get connection state of device
266cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     *
267cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     * @return device connection state
268cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo     */
269cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    @Override
270cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    public int getConnectionState(BluetoothDevice device) {
271cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (DBG) {
272cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            log("getConnectionState(" + device + ")");
273cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
274cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService != null && isEnabled() && isValidDevice(device)) {
275cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            try {
276cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return mService.getConnectionState(device);
277cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            } catch (RemoteException e) {
278cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
279cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                return BluetoothProfile.STATE_DISCONNECTED;
280cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
281cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
282cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (mService == null) {
283cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            Log.w(TAG, "Proxy not attached to service");
284cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
285cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        return BluetoothProfile.STATE_DISCONNECTED;
286cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    }
287cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo
288cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    private final ServiceConnection mConnection = new ServiceConnection() {
289cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        public void onServiceConnected(ComponentName className, IBinder service) {
290cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            if (DBG) {
291cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                log("Proxy object connected");
292cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
293cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            mService = IBluetoothPbapClient.Stub.asInterface(service);
294cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            if (mServiceListener != null) {
295cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT, BluetoothPbapClient.this);
296cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
297cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
298cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        public void onServiceDisconnected(ComponentName className) {
299cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            if (DBG) {
300cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                log("Proxy object disconnected");
301cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
302cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            mService = null;
303cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            if (mServiceListener != null) {
304cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo                mServiceListener.onServiceDisconnected(BluetoothProfile.PBAP_CLIENT);
305cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            }
306cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
307cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    };
308cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo
309cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    private static void log(String msg) {
310cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        Log.d(TAG, msg);
311cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    }
312cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo
313cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    private boolean isEnabled() {
314cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
315cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) {
316cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo            return true;
317cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        }
318cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        log("Bluetooth is Not enabled");
319cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo        return false;
320cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    }
321cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo
322cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    private boolean isValidDevice(BluetoothDevice device) {
323cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo       if (device == null) {
324cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo           return false;
325cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo       }
326cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
327cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo           return true;
328cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo       }
329cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo       return false;
330cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo    }
331cfa8a6469463ace9c3336e3686d950792a2c7ad4Joseph Pirozzo}
332