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;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
2341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganeshimport android.os.ParcelUuid;
2462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.os.RemoteException;
2562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.os.ServiceManager;
2662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.server.BluetoothA2dpService;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2903cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.ArrayList;
3003cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.List;
3162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
3462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth A2DP
3562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile.
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
3762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh *<p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP
3862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
3962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * the BluetoothA2dp proxy object.
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
4162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> Android only supports one connected Bluetooth A2dp device at a time.
4262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Each method is protected with its appropriate permission.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
4462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshpublic final class BluetoothA2dp implements BluetoothProfile {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "BluetoothA2dp";
46f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project    private static final boolean DBG = false;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
4962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Intent used to broadcast the change in connection state of the A2DP
5062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * profile.
5162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
5262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p>This intent will have 3 extras:
53c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <ul>
54c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
55c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
56c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
57c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * </ul>
5862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
590706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
6062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
6162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
6262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
63c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
64c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * receive.
6562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
6662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
6762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final String ACTION_CONNECTION_STATE_CHANGED =
6862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
7162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Intent used to broadcast the change in the Playing state of the A2DP
7262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * profile.
7362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
7462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p>This intent will have 3 extras:
75c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <ul>
76c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
77c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
780706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
79c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * </ul>
8062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
810706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
8262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING},
8362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
84c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
85c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * receive.
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
8862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final String ACTION_PLAYING_STATE_CHANGED =
8962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
9262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * A2DP sink device is streaming music. This state can be one of
9362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
9462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
9562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
9662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final int STATE_PLAYING   =  10;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
9962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * A2DP sink device is NOT streaming music. This state can be one of
10062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
10162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
10262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
10362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final int STATE_NOT_PLAYING   =  11;
104bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
10562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private ServiceListener mServiceListener;
10662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private IBluetoothA2dp mService;
10762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private BluetoothAdapter mAdapter;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a BluetoothA2dp proxy object for interacting with the local
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Bluetooth A2DP service.
11262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /*package*/ BluetoothA2dp(Context mContext, ServiceListener l) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IBinder b = ServiceManager.getService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE);
11662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        mServiceListener = l;
11762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        mAdapter = BluetoothAdapter.getDefaultAdapter();
118081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan        if (b != null) {
119081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan            mService = IBluetoothA2dp.Stub.asInterface(b);
12062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            if (mServiceListener != null) {
12162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                mServiceListener.onServiceConnected(BluetoothProfile.A2DP, this);
12262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
123081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan        } else {
124081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan            Log.w(TAG, "Bluetooth A2DP service not available!");
125081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan
126081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan            // Instead of throwing an exception which prevents people from going
127081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan            // into Wireless settings in the emulator. Let it crash later when it is actually used.
128081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan            mService = null;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh    /*package*/ void close() {
1339bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh        mServiceListener = null;
1349bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh    }
1359bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh
13662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
137f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Initiate connection to a profile of the remote bluetooth device.
138f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
139f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> Currently, the system supports only 1 connection to the
140f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * A2DP profile. The API will automatically disconnect connected
141f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * devices before connecting.
142f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
143f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> This API returns false in scenarios like the profile on the
144f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * device is already connected or Bluetooth is not turned on.
145f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * When this API returns true, it is guaranteed that
146f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * connection state intent for the profile will be broadcasted with
147f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * the state. Users can get the connection state of the profile
148f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * from this intent.
149f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
150f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
151f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
152f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
153f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Remote Bluetooth Device
154f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return false on immediate error,
155f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *               true otherwise
15662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean connect(BluetoothDevice device) {
15962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("connect(" + device + ")");
16062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
16162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
16262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
16362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.connect(device);
16462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
16562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
16662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
16762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
17062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
174f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Initiate disconnection from a profile
175f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
176f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> This API will return false in scenarios like the profile on the
177f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Bluetooth device is not in connected state etc. When this API returns,
178f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * true, it is guaranteed that the connection state change
179f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * intent will be broadcasted with the state. Users can get the
180f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * disconnection state of the profile from this intent.
181f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
182f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> If the disconnection is initiated by a remote device, the state
183f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * will transition from {@link #STATE_CONNECTED} to
184f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
185f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * host (local) device the state will transition from
186f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
187f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * state {@link #STATE_DISCONNECTED}. The transition to
188f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
189f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * two scenarios.
190f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
191f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
192f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
193f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
194f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Remote Bluetooth Device
195f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return false on immediate error,
196f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *               true otherwise
19762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean disconnect(BluetoothDevice device) {
20062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("disconnect(" + device + ")");
20162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
20262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
20362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
20462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.disconnect(device);
20562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
20662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
20762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
20862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
21162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
21562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
216f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan     */
21703cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh    public List<BluetoothDevice> getConnectedDevices() {
21862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getConnectedDevices()");
21962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
22062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
22103cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return mService.getConnectedDevices();
22262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
22362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
22403cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return new ArrayList<BluetoothDevice>();
22562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
226f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan        }
22762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
22803cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh        return new ArrayList<BluetoothDevice>();
229f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan    }
230f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan
23162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
23262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
233f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan     */
23403cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
23562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getDevicesMatchingStates()");
23662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
23762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
23803cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return mService.getDevicesMatchingConnectionStates(states);
23962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
24062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
24103cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return new ArrayList<BluetoothDevice>();
24262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
243f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan        }
24462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
24503cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh        return new ArrayList<BluetoothDevice>();
246f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan    }
247f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan
24862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
24962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
25162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public int getConnectionState(BluetoothDevice device) {
25262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getState(" + device + ")");
25362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
25462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
25562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
25662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.getConnectionState(device);
25762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
25862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
25962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return BluetoothProfile.STATE_DISCONNECTED;
26062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
26162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        }
26262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
26362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return BluetoothProfile.STATE_DISCONNECTED;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
267f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Set priority of the profile
268f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
269f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The device should already be paired.
270f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *  Priority can be one of {@link #PRIORITY_ON} or
271f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_OFF},
272f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
273f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
274f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
275f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
276f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Paired bluetooth device
277f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param priority
278f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return true if priority is set, false on error
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
28162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean setPriority(BluetoothDevice device, int priority) {
28262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("setPriority(" + device + ", " + priority + ")");
28362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
28462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
28562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            if (priority != BluetoothProfile.PRIORITY_OFF &&
28662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                priority != BluetoothProfile.PRIORITY_ON) {
28762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh              return false;
28862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
28962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
29062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.setPriority(device, priority);
29162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
29262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
29362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
29462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
29762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
301f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Get the priority of the profile.
302f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
303f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The priority can be any of:
304f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
305f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
306f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
307f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
308f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
309f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Bluetooth device
310f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return priority of the device
311b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh     * @hide
312b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh     */
31362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public int getPriority(BluetoothDevice device) {
31462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getPriority(" + device + ")");
31562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
31662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
31762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
31862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.getPriority(device);
31962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
32062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
32162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return BluetoothProfile.PRIORITY_OFF;
32262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
323b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh        }
32462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
32562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return BluetoothProfile.PRIORITY_OFF;
326b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh    }
327b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh
32862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
32962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Check if A2DP profile is streaming music.
33062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
331c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
33262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
33362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @param device BluetoothDevice device
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
33562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean isA2dpPlaying(BluetoothDevice device) {
33662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
33762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
33862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
33962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.isA2dpPlaying(device);
34062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
34162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
34262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
34362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
34662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
35062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Initiate suspend from an A2DP sink.
35162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
35262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p> This API will return false in scenarios like the A2DP
35362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * device is not in connected state etc. When this API returns,
354c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * true, it is guaranteed that {@link #ACTION_CONNECTION_STATE_CHANGED}
35562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * intent will be broadcasted with the state. Users can get the
35662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * state of the A2DP device from this intent.
35762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
35862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
359c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * permission.
36062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
36162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @param device Remote A2DP sink
36262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @return false on immediate error,
36362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *               true otherwise
36462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
36662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean suspendSink(BluetoothDevice device) {
36762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
36862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
36962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
37062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.suspendSink(device);
37162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
37262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
37362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
37462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
37762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
38162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Initiate resume from a suspended A2DP sink.
38262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
38362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p> This API will return false in scenarios like the A2DP
38462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * device is not in suspended state etc. When this API returns,
38562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * true, it is guaranteed that {@link #ACTION_SINK_STATE_CHANGED}
38662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * intent will be broadcasted with the state. Users can get the
38762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * state of the A2DP device from this intent.
38862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
38962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
39062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
39162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @param device Remote A2DP sink
39262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @return false on immediate error,
39362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *               true otherwise
39462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
39662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean resumeSink(BluetoothDevice device) {
39762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()
39862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            && isValidDevice(device)) {
39962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
40062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.resumeSink(device);
40162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
40262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
40362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
40462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
40662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
40762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh    /**
41141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     * This function checks if the remote device is an AVCRP
41241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     * target and thus whether we should send volume keys
41341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     * changes or not.
41441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     * @hide
41541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh     */
41641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh    public boolean shouldSendVolumeKeys(BluetoothDevice device) {
41741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh        if (isEnabled() && isValidDevice(device)) {
41841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh            ParcelUuid[] uuids = device.getUuids();
41941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh            if (uuids == null) return false;
42041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh
42141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh            for (ParcelUuid uuid: uuids) {
42241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh                if (BluetoothUuid.isAvrcpTarget(uuid)) {
42341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh                    return true;
42441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh                }
42541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh            }
42641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh        }
42741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh        return false;
42841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh    }
42941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh
430a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie    /**
431a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     * Allow or disallow incoming connection
432a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     * @param device Sink
433a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     * @param value True / False
434a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     * @return Success or Failure of the binder call.
435a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     * @hide
436a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     */
437a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie    public boolean allowIncomingConnect(BluetoothDevice device, boolean value) {
438a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        if (DBG) log("allowIncomingConnect(" + device + ":" + value + ")");
439a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        try {
440a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            return mService.allowIncomingConnect(device, value);
441a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        } catch (RemoteException e) {
442a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            Log.e(TAG, "", e);
443a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            return false;
444a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        }
445a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie    }
446a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie
447a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie    /**
44862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Helper for converting a state to a string.
44962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For debug use only - strings are not internationalized.
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static String stateToString(int state) {
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (state) {
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_DISCONNECTED:
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "disconnected";
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_CONNECTING:
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "connecting";
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_CONNECTED:
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "connected";
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_DISCONNECTING:
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "disconnecting";
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STATE_PLAYING:
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "playing";
46562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        case STATE_NOT_PLAYING:
46662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh          return "not playing";
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "<unknown state " + state + ">";
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
471f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project
47262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private boolean isEnabled() {
47362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
47462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       return false;
47562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    }
47662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
47762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private boolean isValidDevice(BluetoothDevice device) {
47862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (device == null) return false;
47962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
48062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
48162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       return false;
48262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    }
48362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
484f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project    private static void log(String msg) {
48562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh      Log.d(TAG, msg);
486f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project    }
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
488