[go: nahoru, domu]

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