BluetoothA2dp.java revision 3e8c82edb1feafc796aa52efafedc13f794c4dcd
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.bluetooth;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.SdkConstant;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.SdkConstant.SdkConstantType;
213e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xieimport android.content.ComponentName;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
233e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xieimport android.content.Intent;
243e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xieimport android.content.ServiceConnection;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
2641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganeshimport android.os.ParcelUuid;
2762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.os.RemoteException;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3003cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.ArrayList;
3103cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.List;
3262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
3562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth A2DP
3662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile.
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
3862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh *<p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP
3962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
4062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * the BluetoothA2dp proxy object.
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
4262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> Android only supports one connected Bluetooth A2dp device at a time.
4362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Each method is protected with its appropriate permission.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
4562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshpublic final class BluetoothA2dp implements BluetoothProfile {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "BluetoothA2dp";
473e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie    private static final boolean DBG = true;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
5062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Intent used to broadcast the change in connection state of the A2DP
5162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * profile.
5262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
5362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p>This intent will have 3 extras:
54c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <ul>
55c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
56c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
57c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
58c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * </ul>
5962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
600706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
6162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
6262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
6362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
64c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
65c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * receive.
6662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
6762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
6862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final String ACTION_CONNECTION_STATE_CHANGED =
6962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
7262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Intent used to broadcast the change in the Playing state of the A2DP
7362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * profile.
7462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
7562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p>This intent will have 3 extras:
76c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <ul>
77c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
78c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
790706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
80c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * </ul>
8162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
820706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
8362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING},
8462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
85c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
86c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * receive.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
8962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final String ACTION_PLAYING_STATE_CHANGED =
9062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
9362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * A2DP sink device is streaming music. This state can be one of
9462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
9562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
9662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
9762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final int STATE_PLAYING   =  10;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
10062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * A2DP sink device is NOT streaming music. This state can be one of
10162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
10262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
10362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
10462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final int STATE_NOT_PLAYING   =  11;
105bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
1063e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie    private Context mContext;
10762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private ServiceListener mServiceListener;
10862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private IBluetoothA2dp mService;
10962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private BluetoothAdapter mAdapter;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a BluetoothA2dp proxy object for interacting with the local
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Bluetooth A2DP service.
11462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1163e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie    /*package*/ BluetoothA2dp(Context context, ServiceListener l) {
1173e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie        mContext = context;
11862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        mServiceListener = l;
11962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        mAdapter = BluetoothAdapter.getDefaultAdapter();
1203e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie        if (!context.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
1213e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1259bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh    /*package*/ void close() {
1269bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh        mServiceListener = null;
1279bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh    }
1289bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh
12962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
130f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Initiate connection to a profile of the remote bluetooth device.
131f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
132f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> Currently, the system supports only 1 connection to the
133f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * A2DP profile. The API will automatically disconnect connected
134f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * devices before connecting.
135f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
136f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> This API returns false in scenarios like the profile on the
137f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * device is already connected or Bluetooth is not turned on.
138f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * When this API returns true, it is guaranteed that
139f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * connection state intent for the profile will be broadcasted with
140f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * the state. Users can get the connection state of the profile
141f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * from this intent.
142f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
143f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
144f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
145f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
146f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Remote Bluetooth Device
147f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return false on immediate error,
148f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *               true otherwise
14962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean connect(BluetoothDevice device) {
15262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("connect(" + device + ")");
15362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
15462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
15562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
15662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.connect(device);
15762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
15862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
15962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
16062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
16362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
167f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Initiate disconnection from a profile
168f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
169f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> This API will return false in scenarios like the profile on the
170f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Bluetooth device is not in connected state etc. When this API returns,
171f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * true, it is guaranteed that the connection state change
172f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * intent will be broadcasted with the state. Users can get the
173f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * disconnection state of the profile from this intent.
174f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
175f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> If the disconnection is initiated by a remote device, the state
176f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * will transition from {@link #STATE_CONNECTED} to
177f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
178f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * host (local) device the state will transition from
179f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
180f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * state {@link #STATE_DISCONNECTED}. The transition to
181f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
182f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * two scenarios.
183f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
184f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
185f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
186f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
187f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Remote Bluetooth Device
188f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return false on immediate error,
189f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *               true otherwise
19062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean disconnect(BluetoothDevice device) {
19362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("disconnect(" + device + ")");
19462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
19562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
19662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
19762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.disconnect(device);
19862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
19962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
20062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
20162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
20462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
20862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
209f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan     */
21003cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh    public List<BluetoothDevice> getConnectedDevices() {
21162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getConnectedDevices()");
21262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
21362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
21403cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return mService.getConnectedDevices();
21562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
21662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
21703cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return new ArrayList<BluetoothDevice>();
21862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
219f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan        }
22062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
22103cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh        return new ArrayList<BluetoothDevice>();
222f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan    }
223f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan
22462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
22562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
226f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan     */
22703cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
22862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getDevicesMatchingStates()");
22962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
23062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
23103cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return mService.getDevicesMatchingConnectionStates(states);
23262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
23362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
23403cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return new ArrayList<BluetoothDevice>();
23562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
236f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan        }
23762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
23803cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh        return new ArrayList<BluetoothDevice>();
239f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan    }
240f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan
24162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
24262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
24462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public int getConnectionState(BluetoothDevice device) {
24562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getState(" + device + ")");
24662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
24762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
24862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
24962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.getConnectionState(device);
25062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
25162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
25262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return BluetoothProfile.STATE_DISCONNECTED;
25362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
25462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        }
25562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
25662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return BluetoothProfile.STATE_DISCONNECTED;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
260f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Set priority of the profile
261f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
262f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The device should already be paired.
263f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *  Priority can be one of {@link #PRIORITY_ON} or
264f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_OFF},
265f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
266f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
267f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
268f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
269f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Paired bluetooth device
270f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param priority
271f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return true if priority is set, false on error
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
27462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean setPriority(BluetoothDevice device, int priority) {
27562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("setPriority(" + device + ", " + priority + ")");
27662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
27762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
27862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            if (priority != BluetoothProfile.PRIORITY_OFF &&
27962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                priority != BluetoothProfile.PRIORITY_ON) {
28062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh              return false;
28162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
28262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
28362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.setPriority(device, priority);
28462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
28562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
28662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
28762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
29062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
294f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Get the priority of the profile.
295f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
296f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The priority can be any of:
297f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
298f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
299f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
300f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
301f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
302f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Bluetooth device
303f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return priority of the device
304b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh     * @hide
305b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh     */
30662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public int getPriority(BluetoothDevice device) {
30762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getPriority(" + device + ")");
30862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
30962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
31062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
31162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.getPriority(device);
31262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
31362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
31462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return BluetoothProfile.PRIORITY_OFF;
31562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
316b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh        }
31762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
31862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return BluetoothProfile.PRIORITY_OFF;
319b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh    }
320b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh
32162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
32262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Check if A2DP profile is streaming music.
32362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
324c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
32562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
32662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @param device BluetoothDevice device
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
32862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean isA2dpPlaying(BluetoothDevice device) {
32962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
33062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
33162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
33262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.isA2dpPlaying(device);
33362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
33462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
33562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
33662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
33962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
34341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     * This function checks if the remote device is an AVCRP
34441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     * target and thus whether we should send volume keys
34541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     * changes or not.
34641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     * @hide
34741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     */
34841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh    public boolean shouldSendVolumeKeys(BluetoothDevice device) {
34941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh        if (isEnabled() && isValidDevice(device)) {
35041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh            ParcelUuid[] uuids = device.getUuids();
35141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh            if (uuids == null) return false;
35241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh
35341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh            for (ParcelUuid uuid: uuids) {
35441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh                if (BluetoothUuid.isAvrcpTarget(uuid)) {
35541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh                    return true;
35641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh                }
35741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh            }
35841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh        }
35941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh        return false;
36041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh    }
36141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh
362a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie    /**
36362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Helper for converting a state to a string.
36462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For debug use only - strings are not internationalized.
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static String stateToString(int state) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (state) {
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_DISCONNECTED:
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "disconnected";
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_CONNECTING:
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "connecting";
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_CONNECTED:
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "connected";
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_DISCONNECTING:
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "disconnecting";
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_PLAYING:
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "playing";
38062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        case STATE_NOT_PLAYING:
38162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh          return "not playing";
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "<unknown state " + state + ">";
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
386f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project
3873e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie    private ServiceConnection mConnection = new ServiceConnection() {
3883e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie        public void onServiceConnected(ComponentName className, IBinder service) {
3893e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            if (DBG) Log.d(TAG, "Proxy object connected");
3903e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            mService = IBluetoothA2dp.Stub.asInterface(service);
3913e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie
3923e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            if (mServiceListener != null) {
3933e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie                mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this);
3943e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            }
3953e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie        }
3963e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie        public void onServiceDisconnected(ComponentName className) {
3973e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            if (DBG) Log.d(TAG, "Proxy object disconnected");
3983e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            mService = null;
3993e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            if (mServiceListener != null) {
4003e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie                mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP);
4013e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie            }
4023e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie        }
4033e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie    };
4043e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie
40562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private boolean isEnabled() {
40662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
40762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       return false;
40862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    }
40962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
41062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private boolean isValidDevice(BluetoothDevice device) {
41162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (device == null) return false;
41262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
41362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
41462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       return false;
41562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    }
41662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
417f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project    private static void log(String msg) {
41862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh      Log.d(TAG, msg);
419f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project    }
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
421