A2dpService.java revision 15d36984a79d6e35c659edb0efdf929f0b526bd5
1/*
2 * Copyright (C) 2012 Google Inc.
3 */
4package com.android.bluetooth.a2dp;
5
6import android.bluetooth.BluetoothDevice;
7import android.bluetooth.BluetoothProfile;
8import android.bluetooth.IBluetoothA2dp;
9import android.content.Context;
10import android.content.Intent;
11import android.provider.Settings;
12import android.util.Log;
13import java.util.ArrayList;
14import java.util.List;
15import java.util.Iterator;
16import java.util.Map;
17import com.android.bluetooth.btservice.ProfileService;
18
19/**
20 * Provides Bluetooth A2DP profile, as a service in the Bluetooth application.
21 * @hide
22 */
23public class A2dpService extends ProfileService {
24    private static final boolean DBG = true;
25    private static final String TAG="A2dpService";
26
27    private A2dpStateMachine mStateMachine;
28
29    protected String getName() {
30        return TAG;
31    }
32
33    protected IProfileServiceBinder initBinder() {
34        return new BluetoothA2dpBinder(this);
35    }
36
37    protected boolean start() {
38        mStateMachine = new A2dpStateMachine(this,this);
39        mStateMachine.start();
40        return true;
41    }
42
43    protected boolean stop() {
44        mStateMachine.doQuit();
45        return true;
46    }
47
48    protected boolean cleanup() {
49        if (mStateMachine!= null) {
50            mStateMachine.cleanup();
51        }
52        return true;
53    }
54
55    //API Methods
56    boolean connect(BluetoothDevice device) {
57        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
58                                       "Need BLUETOOTH ADMIN permission");
59
60        if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
61            return false;
62        }
63
64        int connectionState = mStateMachine.getConnectionState(device);
65        if (connectionState == BluetoothProfile.STATE_CONNECTED ||
66            connectionState == BluetoothProfile.STATE_CONNECTING) {
67            return false;
68        }
69
70        mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device);
71        return true;
72    }
73
74    boolean disconnect(BluetoothDevice device) {
75        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
76                                       "Need BLUETOOTH ADMIN permission");
77        int connectionState = mStateMachine.getConnectionState(device);
78        if (connectionState != BluetoothProfile.STATE_CONNECTED &&
79            connectionState != BluetoothProfile.STATE_CONNECTING) {
80            return false;
81        }
82
83        mStateMachine.sendMessage(A2dpStateMachine.DISCONNECT, device);
84        return true;
85    }
86
87    List<BluetoothDevice> getConnectedDevices() {
88        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
89        return mStateMachine.getConnectedDevices();
90    }
91
92    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
93        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
94        return mStateMachine.getDevicesMatchingConnectionStates(states);
95    }
96
97    int getConnectionState(BluetoothDevice device) {
98        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
99        return mStateMachine.getConnectionState(device);
100    }
101
102    boolean setPriority(BluetoothDevice device, int priority) {
103        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
104                                       "Need BLUETOOTH_ADMIN permission");
105        Settings.Secure.putInt(getContentResolver(),
106            Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
107            priority);
108        if (DBG) Log.d(TAG,"Saved priority " + device + " = " + priority);
109        return true;
110    }
111
112    int getPriority(BluetoothDevice device) {
113        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
114                                       "Need BLUETOOTH_ADMIN permission");
115        int priority = Settings.Secure.getInt(getContentResolver(),
116            Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
117            BluetoothProfile.PRIORITY_UNDEFINED);
118        return priority;
119    }
120
121    synchronized boolean isA2dpPlaying(BluetoothDevice device) {
122        enforceCallingOrSelfPermission(BLUETOOTH_PERM,
123                                       "Need BLUETOOTH permission");
124        if (DBG) Log.d(TAG, "isA2dpPlaying(" + device + ")");
125        return mStateMachine.isPlaying(device);
126    }
127
128    //Binder object: Must be static class or memory leak may occur
129    private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub
130        implements IProfileServiceBinder {
131        private A2dpService mService;
132
133        private A2dpService getService() {
134            if (mService  != null && mService.isAvailable()) {
135                return mService;
136            }
137            return null;
138        }
139
140        BluetoothA2dpBinder(A2dpService svc) {
141            mService = svc;
142        }
143
144        public boolean cleanup()  {
145            mService = null;
146            return true;
147        }
148
149        public boolean connect(BluetoothDevice device) {
150            A2dpService service = getService();
151            if (service == null) return false;
152            return service.connect(device);
153        }
154
155        public boolean disconnect(BluetoothDevice device) {
156            A2dpService service = getService();
157            if (service == null) return false;
158            return service.disconnect(device);
159        }
160
161        public List<BluetoothDevice> getConnectedDevices() {
162            A2dpService service = getService();
163            if (service == null) return new ArrayList<BluetoothDevice>(0);
164            return service.getConnectedDevices();
165        }
166
167        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
168            A2dpService service = getService();
169            if (service == null) return new ArrayList<BluetoothDevice>(0);
170            return service.getDevicesMatchingConnectionStates(states);
171        }
172
173        public int getConnectionState(BluetoothDevice device) {
174            A2dpService service = getService();
175            if (service == null) return BluetoothProfile.STATE_DISCONNECTED;
176            return service.getConnectionState(device);
177        }
178
179        public boolean setPriority(BluetoothDevice device, int priority) {
180            A2dpService service = getService();
181            if (service == null) return false;
182            return service.setPriority(device, priority);
183        }
184
185        public int getPriority(BluetoothDevice device) {
186            A2dpService service = getService();
187            if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED;
188            return service.getPriority(device);
189        }
190
191        public boolean isA2dpPlaying(BluetoothDevice device) {
192            A2dpService service = getService();
193            if (service == null) return false;
194            return service.isA2dpPlaying(device);
195        }
196    };
197}
198