A2dpProfile.java revision c7b490c7a03dff00faf859d6aba3440b6a3921d5
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settings.bluetooth;
18
19import android.bluetooth.BluetoothA2dp;
20import android.bluetooth.BluetoothAdapter;
21import android.bluetooth.BluetoothClass;
22import android.bluetooth.BluetoothDevice;
23import android.bluetooth.BluetoothProfile;
24import android.bluetooth.BluetoothUuid;
25import android.content.Context;
26import android.os.ParcelUuid;
27import android.util.Log;
28
29import com.android.settings.R;
30
31import java.util.List;
32
33final class A2dpProfile implements LocalBluetoothProfile {
34    private static final String TAG = "A2dpProfile";
35    private static boolean V = true;
36
37    private BluetoothA2dp mService;
38    private boolean mIsProfileReady;
39
40    static final ParcelUuid[] SINK_UUIDS = {
41        BluetoothUuid.AudioSink,
42        BluetoothUuid.AdvAudioDist,
43    };
44
45    static final String NAME = "A2DP";
46    private final LocalBluetoothProfileManager mProfileManager;
47
48    // Order of this profile in device profiles list
49    private static final int ORDINAL = 1;
50
51    // These callbacks run on the main thread.
52    private final class A2dpServiceListener
53            implements BluetoothProfile.ServiceListener {
54
55        public void onServiceConnected(int profile, BluetoothProfile proxy) {
56            if (V) Log.d(TAG,"Bluetooth service disconnected");
57            mService = (BluetoothA2dp) proxy;
58            mProfileManager.setA2dpServiceUp(true);
59            mIsProfileReady=true;
60        }
61
62        public void onServiceDisconnected(int profile) {
63            if (V) Log.d(TAG,"Bluetooth service disconnected");
64            mProfileManager.setA2dpServiceUp(false);
65            mIsProfileReady=false;
66        }
67    }
68
69    public boolean isProfileReady() {
70        return mIsProfileReady;
71    }
72    A2dpProfile(Context context, LocalBluetoothProfileManager profileManager) {
73
74        mProfileManager = profileManager;
75        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
76        adapter.getProfileProxy(context, new A2dpServiceListener(),
77                BluetoothProfile.A2DP);
78    }
79
80    public boolean isConnectable() {
81        return true;
82    }
83
84    public boolean isAutoConnectable() {
85        return true;
86    }
87
88    public List<BluetoothDevice> getConnectedDevices() {
89        return mService.getDevicesMatchingConnectionStates(
90              new int[] {BluetoothProfile.STATE_CONNECTED,
91                         BluetoothProfile.STATE_CONNECTING,
92                         BluetoothProfile.STATE_DISCONNECTING});
93    }
94
95    public boolean connect(BluetoothDevice device) {
96        List<BluetoothDevice> sinks = getConnectedDevices();
97        if (sinks != null) {
98            for (BluetoothDevice sink : sinks) {
99                mService.disconnect(sink);
100            }
101        }
102        return mService.connect(device);
103    }
104
105    public boolean disconnect(BluetoothDevice device) {
106        return mService.disconnect(device);
107    }
108
109    // This function is added as the AUTO CONNECT priority could not be set by using setPreferred(),
110    // as setPreferred() takes only boolean input but getPreferred() supports interger output.
111    // Also this need not implemented by all profiles so this has been added here.
112    public void enableAutoConnect(BluetoothDevice device, boolean enable) {
113        if (enable) {
114             mService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
115        } else {
116             if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
117                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
118             }
119        }
120    }
121
122    public int getConnectionStatus(BluetoothDevice device) {
123        return mService.getConnectionState(device);
124    }
125
126    public boolean isPreferred(BluetoothDevice device) {
127        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
128    }
129
130    public int getPreferred(BluetoothDevice device) {
131        return mService.getPriority(device);
132    }
133
134    public void setPreferred(BluetoothDevice device, boolean preferred) {
135        if (preferred) {
136            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
137                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
138            }
139        } else {
140            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
141        }
142    }
143
144    boolean isA2dpPlaying() {
145        List<BluetoothDevice> sinks = mService.getConnectedDevices();
146        if (!sinks.isEmpty()) {
147            if (mService.isA2dpPlaying(sinks.get(0))) {
148                return true;
149            }
150        }
151        return false;
152    }
153
154    public String toString() {
155        return NAME;
156    }
157
158    public int getOrdinal() {
159        return ORDINAL;
160    }
161
162    public int getNameResource(BluetoothDevice device) {
163        return R.string.bluetooth_profile_a2dp;
164    }
165
166    public int getSummaryResourceForDevice(BluetoothDevice device) {
167        int state = mService.getConnectionState(device);
168        switch (state) {
169            case BluetoothProfile.STATE_DISCONNECTED:
170            {
171                setPreferred(device, false);
172                return R.string.bluetooth_a2dp_profile_summary_use_for;
173            }
174            case BluetoothProfile.STATE_CONNECTED:
175            {
176                setPreferred(device, true);
177                return R.string.bluetooth_a2dp_profile_summary_connected;
178            }
179            default:
180                return Utils.getConnectionStateSummary(state);
181        }
182    }
183
184    public int getDrawableResource(BluetoothClass btClass) {
185        return R.drawable.ic_bt_headphones_a2dp;
186    }
187
188    protected void finalize() {
189        if (V) Log.d(TAG, "finalize()");
190        if (mService != null) {
191            try {
192                BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.A2DP, mService);
193                mService = null;
194            }catch (Throwable t) {
195                Log.w(TAG, "Error cleaning up A2DP proxy", t);
196            }
197        }
198    }
199}
200