16c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */
16ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu
176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiepackage com.android.bluetooth.a2dp;
186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.BluetoothDevice;
206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.BluetoothProfile;
216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.IBluetoothA2dp;
226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.content.Context;
236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.content.Intent;
246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.provider.Settings;
256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.util.Log;
2637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.btservice.ProfileService;
2737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.Utils;
2874ae04c73312403e89db0f8e9bd9601d403b4783fredcimport java.util.ArrayList;
296654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Iterator;
3037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport java.util.List;
316654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Map;
326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/**
346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie * Provides Bluetooth A2DP profile, as a service in the Bluetooth application.
356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie * @hide
366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */
37b5cc776c9353a203cdde97e62b25f05d9633d14cfredcpublic class A2dpService extends ProfileService {
38fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie    private static final boolean DBG = false;
39b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    private static final String TAG="A2dpService";
406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private A2dpStateMachine mStateMachine;
42c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu    private Avrcp mAvrcp;
434f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private static A2dpService sAd2dpService;
446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4574ae04c73312403e89db0f8e9bd9601d403b4783fredc    protected String getName() {
4674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return TAG;
4774ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
4874ae04c73312403e89db0f8e9bd9601d403b4783fredc
4974ae04c73312403e89db0f8e9bd9601d403b4783fredc    protected IProfileServiceBinder initBinder() {
5074ae04c73312403e89db0f8e9bd9601d403b4783fredc        return new BluetoothA2dpBinder(this);
5174ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
53b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected boolean start() {
54c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu        mAvrcp = Avrcp.make(this);
55d3195daf68329036df6a01331b466844b5cb29deZhihai Xu        mStateMachine = A2dpStateMachine.make(this, this);
564f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        setA2dpService(this);
57b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        return true;
586654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
596654f5c903de510a70f9e72cd5ad7837b615d93ffredc
60b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected boolean stop() {
6115d36984a79d6e35c659edb0efdf929f0b526bd5Fred        mStateMachine.doQuit();
62c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu        mAvrcp.doQuit();
6374ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
6474ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
6574ae04c73312403e89db0f8e9bd9601d403b4783fredc
6674ae04c73312403e89db0f8e9bd9601d403b4783fredc    protected boolean cleanup() {
676654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (mStateMachine!= null) {
686654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mStateMachine.cleanup();
696654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
70c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu        if (mAvrcp != null) {
71c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu            mAvrcp.cleanup();
72c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu            mAvrcp = null;
73c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu        }
744f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        clearA2dpService();
75b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        return true;
76b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
776654f5c903de510a70f9e72cd5ad7837b615d93ffredc
7874ae04c73312403e89db0f8e9bd9601d403b4783fredc    //API Methods
794f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
804f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    public static synchronized A2dpService getA2dpService(){
814f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (sAd2dpService != null && sAd2dpService.isAvailable()) {
824f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            if (DBG) Log.d(TAG, "getA2DPService(): returning " + sAd2dpService);
834f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            return sAd2dpService;
844f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
854f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (DBG)  {
864f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            if (sAd2dpService == null) {
874f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                Log.d(TAG, "getA2dpService(): service is NULL");
884f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            } else if (!(sAd2dpService.isAvailable())) {
894f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                Log.d(TAG,"getA2dpService(): service is not available");
904f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            }
914f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
924f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        return null;
934f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
944f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
954f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private static synchronized void setA2dpService(A2dpService instance) {
964f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        if (instance != null && instance.isAvailable()) {
974f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            if (DBG) Log.d(TAG, "setA2dpService(): set to: " + sAd2dpService);
984f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            sAd2dpService = instance;
994f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        } else {
1004f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            if (DBG)  {
1014f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                if (sAd2dpService == null) {
1024f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                    Log.d(TAG, "setA2dpService(): service not available");
1034f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                } else if (!sAd2dpService.isAvailable()) {
1044f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                    Log.d(TAG,"setA2dpService(): service is cleaning up");
1054f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta                }
1064f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta            }
1074f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        }
1084f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
1094f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
1104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    private static synchronized void clearA2dpService() {
1114f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta        sAd2dpService = null;
1124f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    }
1134f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta
1144f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    public boolean connect(BluetoothDevice device) {
11574ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
11674ae04c73312403e89db0f8e9bd9601d403b4783fredc                                       "Need BLUETOOTH ADMIN permission");
11774ae04c73312403e89db0f8e9bd9601d403b4783fredc
11874ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
11974ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
12074ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
12174ae04c73312403e89db0f8e9bd9601d403b4783fredc
12274ae04c73312403e89db0f8e9bd9601d403b4783fredc        int connectionState = mStateMachine.getConnectionState(device);
12374ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (connectionState == BluetoothProfile.STATE_CONNECTED ||
12474ae04c73312403e89db0f8e9bd9601d403b4783fredc            connectionState == BluetoothProfile.STATE_CONNECTING) {
12574ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
12674ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
12774ae04c73312403e89db0f8e9bd9601d403b4783fredc
12874ae04c73312403e89db0f8e9bd9601d403b4783fredc        mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device);
12974ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
130b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
131b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
13274ae04c73312403e89db0f8e9bd9601d403b4783fredc    boolean disconnect(BluetoothDevice device) {
13374ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
13474ae04c73312403e89db0f8e9bd9601d403b4783fredc                                       "Need BLUETOOTH ADMIN permission");
13574ae04c73312403e89db0f8e9bd9601d403b4783fredc        int connectionState = mStateMachine.getConnectionState(device);
13674ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (connectionState != BluetoothProfile.STATE_CONNECTED &&
13774ae04c73312403e89db0f8e9bd9601d403b4783fredc            connectionState != BluetoothProfile.STATE_CONNECTING) {
13874ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
13974ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
14074ae04c73312403e89db0f8e9bd9601d403b4783fredc
14174ae04c73312403e89db0f8e9bd9601d403b4783fredc        mStateMachine.sendMessage(A2dpStateMachine.DISCONNECT, device);
14274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
1436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1454f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    public List<BluetoothDevice> getConnectedDevices() {
14674ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
14774ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mStateMachine.getConnectedDevices();
14874ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
1496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
15074ae04c73312403e89db0f8e9bd9601d403b4783fredc    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
15174ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
15274ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mStateMachine.getDevicesMatchingConnectionStates(states);
15374ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
1546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
15574ae04c73312403e89db0f8e9bd9601d403b4783fredc    int getConnectionState(BluetoothDevice device) {
15674ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
15774ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mStateMachine.getConnectionState(device);
15874ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
15974ae04c73312403e89db0f8e9bd9601d403b4783fredc
1604f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    public boolean setPriority(BluetoothDevice device, int priority) {
16174ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
16274ae04c73312403e89db0f8e9bd9601d403b4783fredc                                       "Need BLUETOOTH_ADMIN permission");
163c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey        Settings.Global.putInt(getContentResolver(),
164c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey            Settings.Global.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
16574ae04c73312403e89db0f8e9bd9601d403b4783fredc            priority);
16674ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (DBG) Log.d(TAG,"Saved priority " + device + " = " + priority);
16774ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
16874ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
1696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1704f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta    public int getPriority(BluetoothDevice device) {
17174ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
17274ae04c73312403e89db0f8e9bd9601d403b4783fredc                                       "Need BLUETOOTH_ADMIN permission");
173c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey        int priority = Settings.Global.getInt(getContentResolver(),
174c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey            Settings.Global.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
17574ae04c73312403e89db0f8e9bd9601d403b4783fredc            BluetoothProfile.PRIORITY_UNDEFINED);
17674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return priority;
17774ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
17874ae04c73312403e89db0f8e9bd9601d403b4783fredc
17917675906064bb72fdcca75baa56cdf8bb8968d01John Du    /* Absolute volume implementation */
18017675906064bb72fdcca75baa56cdf8bb8968d01John Du    public boolean isAvrcpAbsoluteVolumeSupported() {
18117675906064bb72fdcca75baa56cdf8bb8968d01John Du        return mAvrcp.isAbsoluteVolumeSupported();
18217675906064bb72fdcca75baa56cdf8bb8968d01John Du    }
18317675906064bb72fdcca75baa56cdf8bb8968d01John Du
18417675906064bb72fdcca75baa56cdf8bb8968d01John Du    public void adjustAvrcpAbsoluteVolume(int direction) {
18517675906064bb72fdcca75baa56cdf8bb8968d01John Du        mAvrcp.adjustVolume(direction);
18617675906064bb72fdcca75baa56cdf8bb8968d01John Du    }
18717675906064bb72fdcca75baa56cdf8bb8968d01John Du
18817675906064bb72fdcca75baa56cdf8bb8968d01John Du    public void setAvrcpAbsoluteVolume(int volume) {
18917675906064bb72fdcca75baa56cdf8bb8968d01John Du        mAvrcp.setAbsoluteVolume(volume);
19017675906064bb72fdcca75baa56cdf8bb8968d01John Du    }
19117675906064bb72fdcca75baa56cdf8bb8968d01John Du
192d3195daf68329036df6a01331b466844b5cb29deZhihai Xu    public void setAvrcpAudioState(int state) {
193d3195daf68329036df6a01331b466844b5cb29deZhihai Xu        mAvrcp.setA2dpAudioState(state);
194d3195daf68329036df6a01331b466844b5cb29deZhihai Xu    }
195d3195daf68329036df6a01331b466844b5cb29deZhihai Xu
19674ae04c73312403e89db0f8e9bd9601d403b4783fredc    synchronized boolean isA2dpPlaying(BluetoothDevice device) {
19774ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM,
19874ae04c73312403e89db0f8e9bd9601d403b4783fredc                                       "Need BLUETOOTH permission");
19974ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (DBG) Log.d(TAG, "isA2dpPlaying(" + device + ")");
20074ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mStateMachine.isPlaying(device);
20174ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
20274ae04c73312403e89db0f8e9bd9601d403b4783fredc
20374ae04c73312403e89db0f8e9bd9601d403b4783fredc    //Binder object: Must be static class or memory leak may occur
20474ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub
20574ae04c73312403e89db0f8e9bd9601d403b4783fredc        implements IProfileServiceBinder {
20674ae04c73312403e89db0f8e9bd9601d403b4783fredc        private A2dpService mService;
20774ae04c73312403e89db0f8e9bd9601d403b4783fredc
20874ae04c73312403e89db0f8e9bd9601d403b4783fredc        private A2dpService getService() {
20937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
21037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"A2dp call not allowed for non-active user");
21137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return null;
21237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
21337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
21437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (mService != null && mService.isAvailable()) {
21574ae04c73312403e89db0f8e9bd9601d403b4783fredc                return mService;
2166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            }
21774ae04c73312403e89db0f8e9bd9601d403b4783fredc            return null;
21874ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
2196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
22074ae04c73312403e89db0f8e9bd9601d403b4783fredc        BluetoothA2dpBinder(A2dpService svc) {
22174ae04c73312403e89db0f8e9bd9601d403b4783fredc            mService = svc;
22274ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
22374ae04c73312403e89db0f8e9bd9601d403b4783fredc
22474ae04c73312403e89db0f8e9bd9601d403b4783fredc        public boolean cleanup()  {
22574ae04c73312403e89db0f8e9bd9601d403b4783fredc            mService = null;
2266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            return true;
2276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
22974ae04c73312403e89db0f8e9bd9601d403b4783fredc        public boolean connect(BluetoothDevice device) {
23074ae04c73312403e89db0f8e9bd9601d403b4783fredc            A2dpService service = getService();
23174ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
23274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.connect(device);
23374ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
2346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
23574ae04c73312403e89db0f8e9bd9601d403b4783fredc        public boolean disconnect(BluetoothDevice device) {
23674ae04c73312403e89db0f8e9bd9601d403b4783fredc            A2dpService service = getService();
23774ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
23874ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.disconnect(device);
2396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        public List<BluetoothDevice> getConnectedDevices() {
24274ae04c73312403e89db0f8e9bd9601d403b4783fredc            A2dpService service = getService();
24374ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return new ArrayList<BluetoothDevice>(0);
24474ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getConnectedDevices();
2456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
24874ae04c73312403e89db0f8e9bd9601d403b4783fredc            A2dpService service = getService();
24974ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return new ArrayList<BluetoothDevice>(0);
25074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getDevicesMatchingConnectionStates(states);
2516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        public int getConnectionState(BluetoothDevice device) {
25474ae04c73312403e89db0f8e9bd9601d403b4783fredc            A2dpService service = getService();
25574ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return BluetoothProfile.STATE_DISCONNECTED;
25674ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getConnectionState(device);
2576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        public boolean setPriority(BluetoothDevice device, int priority) {
26074ae04c73312403e89db0f8e9bd9601d403b4783fredc            A2dpService service = getService();
26174ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
26274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.setPriority(device, priority);
2636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        public int getPriority(BluetoothDevice device) {
26674ae04c73312403e89db0f8e9bd9601d403b4783fredc            A2dpService service = getService();
26774ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED;
26874ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getPriority(device);
2696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
27117675906064bb72fdcca75baa56cdf8bb8968d01John Du        public boolean isAvrcpAbsoluteVolumeSupported() {
27217675906064bb72fdcca75baa56cdf8bb8968d01John Du            A2dpService service = getService();
27317675906064bb72fdcca75baa56cdf8bb8968d01John Du            if (service == null) return false;
27417675906064bb72fdcca75baa56cdf8bb8968d01John Du            return service.isAvrcpAbsoluteVolumeSupported();
27517675906064bb72fdcca75baa56cdf8bb8968d01John Du        }
27617675906064bb72fdcca75baa56cdf8bb8968d01John Du
27717675906064bb72fdcca75baa56cdf8bb8968d01John Du        public void adjustAvrcpAbsoluteVolume(int direction) {
27817675906064bb72fdcca75baa56cdf8bb8968d01John Du            A2dpService service = getService();
27917675906064bb72fdcca75baa56cdf8bb8968d01John Du            if (service == null) return;
28017675906064bb72fdcca75baa56cdf8bb8968d01John Du            service.adjustAvrcpAbsoluteVolume(direction);
28117675906064bb72fdcca75baa56cdf8bb8968d01John Du        }
28217675906064bb72fdcca75baa56cdf8bb8968d01John Du
28317675906064bb72fdcca75baa56cdf8bb8968d01John Du        public void setAvrcpAbsoluteVolume(int volume) {
28417675906064bb72fdcca75baa56cdf8bb8968d01John Du            A2dpService service = getService();
28517675906064bb72fdcca75baa56cdf8bb8968d01John Du            if (service == null) return;
28617675906064bb72fdcca75baa56cdf8bb8968d01John Du            service.setAvrcpAbsoluteVolume(volume);
28717675906064bb72fdcca75baa56cdf8bb8968d01John Du        }
28817675906064bb72fdcca75baa56cdf8bb8968d01John Du
28974ae04c73312403e89db0f8e9bd9601d403b4783fredc        public boolean isA2dpPlaying(BluetoothDevice device) {
29074ae04c73312403e89db0f8e9bd9601d403b4783fredc            A2dpService service = getService();
29174ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
29274ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.isA2dpPlaying(device);
2936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    };
2956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
296