1/*
2 * Copyright (C) 2014 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.systemui.statusbar.policy;
18
19import android.bluetooth.BluetoothA2dp;
20import android.bluetooth.BluetoothA2dpSink;
21import android.bluetooth.BluetoothAdapter;
22import android.bluetooth.BluetoothDevice;
23import android.bluetooth.BluetoothHeadset;
24import android.bluetooth.BluetoothHeadsetClient;
25import android.bluetooth.BluetoothInputDevice;
26import android.bluetooth.BluetoothMap;
27import android.bluetooth.BluetoothPan;
28import android.bluetooth.BluetoothProfile;
29import android.bluetooth.BluetoothUuid;
30import android.os.ParcelUuid;
31import android.text.TextUtils;
32
33public class BluetoothUtil {
34
35    public static String profileToString(int profile) {
36        if (profile == BluetoothProfile.HEADSET) return "HEADSET";
37        if (profile == BluetoothProfile.A2DP) return "A2DP";
38        if (profile == BluetoothProfile.AVRCP_CONTROLLER) return "AVRCP_CONTROLLER";
39        if (profile == BluetoothProfile.PAN) return "PAN";
40        if (profile == BluetoothProfile.INPUT_DEVICE) return "INPUT_DEVICE";
41        if (profile == BluetoothProfile.MAP) return "MAP";
42        return "UNKNOWN(" + profile + ")";
43    }
44
45    public static String profileStateToString(int state) {
46        if (state == BluetoothProfile.STATE_CONNECTED) return "STATE_CONNECTED";
47        if (state == BluetoothProfile.STATE_CONNECTING) return "STATE_CONNECTING";
48        if (state == BluetoothProfile.STATE_DISCONNECTED) return "STATE_DISCONNECTED";
49        if (state == BluetoothProfile.STATE_DISCONNECTING) return "STATE_DISCONNECTING";
50        return "STATE_UNKNOWN";
51    }
52
53    public static String uuidToString(ParcelUuid uuid) {
54        if (BluetoothUuid.AudioSink.equals(uuid)) return "AudioSink";
55        if (BluetoothUuid.AudioSource.equals(uuid)) return "AudioSource";
56        if (BluetoothUuid.AdvAudioDist.equals(uuid)) return "AdvAudioDist";
57        if (BluetoothUuid.HSP.equals(uuid)) return "HSP";
58        if (BluetoothUuid.HSP_AG.equals(uuid)) return "HSP_AG";
59        if (BluetoothUuid.Handsfree.equals(uuid)) return "Handsfree";
60        if (BluetoothUuid.Handsfree_AG.equals(uuid)) return "Handsfree_AG";
61        if (BluetoothUuid.AvrcpController.equals(uuid)) return "AvrcpController";
62        if (BluetoothUuid.AvrcpTarget.equals(uuid)) return "AvrcpTarget";
63        if (BluetoothUuid.ObexObjectPush.equals(uuid)) return "ObexObjectPush";
64        if (BluetoothUuid.Hid.equals(uuid)) return "Hid";
65        if (BluetoothUuid.Hogp.equals(uuid)) return "Hogp";
66        if (BluetoothUuid.PANU.equals(uuid)) return "PANU";
67        if (BluetoothUuid.NAP.equals(uuid)) return "NAP";
68        if (BluetoothUuid.BNEP.equals(uuid)) return "BNEP";
69        if (BluetoothUuid.PBAP_PSE.equals(uuid)) return "PBAP_PSE";
70        if (BluetoothUuid.MAP.equals(uuid)) return "MAP";
71        if (BluetoothUuid.MNS.equals(uuid)) return "MNS";
72        if (BluetoothUuid.MAS.equals(uuid)) return "MAS";
73        return uuid != null ? uuid.toString() : null;
74    }
75
76    public static String connectionStateToString(int connectionState) {
77        if (connectionState == BluetoothAdapter.STATE_DISCONNECTED) return "STATE_DISCONNECTED";
78        if (connectionState == BluetoothAdapter.STATE_CONNECTED) return "STATE_CONNECTED";
79        if (connectionState == BluetoothAdapter.STATE_DISCONNECTING) return "STATE_DISCONNECTING";
80        if (connectionState == BluetoothAdapter.STATE_CONNECTING) return "STATE_CONNECTING";
81        return "ERROR";
82    }
83
84    public static String deviceToString(BluetoothDevice device) {
85        return device == null ? null : (device.getAddress() + '[' + device.getAliasName() + ']');
86    }
87
88    public static String uuidsToString(BluetoothDevice device) {
89        if (device == null) return null;
90        final ParcelUuid[] ids = device.getUuids();
91        if (ids == null) return null;
92        final String[] tokens = new String[ids.length];
93        for (int i = 0; i < tokens.length; i++) {
94            tokens[i] = uuidToString(ids[i]);
95        }
96        return TextUtils.join(",", tokens);
97    }
98
99    public static int uuidToProfile(ParcelUuid uuid) {
100        if (BluetoothUuid.AudioSink.equals(uuid)) return BluetoothProfile.A2DP;
101        if (BluetoothUuid.AdvAudioDist.equals(uuid)) return BluetoothProfile.A2DP;
102
103        if (BluetoothUuid.HSP.equals(uuid)) return BluetoothProfile.HEADSET;
104        if (BluetoothUuid.Handsfree.equals(uuid)) return BluetoothProfile.HEADSET;
105
106        if (BluetoothUuid.MAP.equals(uuid)) return BluetoothProfile.MAP;
107        if (BluetoothUuid.MNS.equals(uuid)) return BluetoothProfile.MAP;
108        if (BluetoothUuid.MAS.equals(uuid)) return BluetoothProfile.MAP;
109
110        if (BluetoothUuid.AvrcpController.equals(uuid)) return BluetoothProfile.AVRCP_CONTROLLER;
111
112        if (BluetoothUuid.Hid.equals(uuid)) return BluetoothProfile.INPUT_DEVICE;
113        if (BluetoothUuid.Hogp.equals(uuid)) return BluetoothProfile.INPUT_DEVICE;
114
115        if (BluetoothUuid.NAP.equals(uuid)) return BluetoothProfile.PAN;
116
117        return 0;
118    }
119
120    public static Profile getProfile(BluetoothProfile p) {
121        if (p instanceof BluetoothA2dp) return newProfile((BluetoothA2dp) p);
122        if (p instanceof BluetoothHeadset) return newProfile((BluetoothHeadset) p);
123        if (p instanceof BluetoothA2dpSink) return newProfile((BluetoothA2dpSink) p);
124        if (p instanceof BluetoothHeadsetClient) return newProfile((BluetoothHeadsetClient) p);
125        if (p instanceof BluetoothInputDevice) return newProfile((BluetoothInputDevice) p);
126        if (p instanceof BluetoothMap) return newProfile((BluetoothMap) p);
127        if (p instanceof BluetoothPan) return newProfile((BluetoothPan) p);
128        return null;
129    }
130
131    private static Profile newProfile(final BluetoothA2dp a2dp) {
132        return new Profile() {
133            @Override
134            public boolean connect(BluetoothDevice device) {
135                return a2dp.connect(device);
136            }
137
138            @Override
139            public boolean disconnect(BluetoothDevice device) {
140                return a2dp.disconnect(device);
141            }
142        };
143    }
144
145    private static Profile newProfile(final BluetoothHeadset headset) {
146        return new Profile() {
147            @Override
148            public boolean connect(BluetoothDevice device) {
149                return headset.connect(device);
150            }
151
152            @Override
153            public boolean disconnect(BluetoothDevice device) {
154                return headset.disconnect(device);
155            }
156        };
157    }
158
159    private static Profile newProfile(final BluetoothA2dpSink sink) {
160        return new Profile() {
161            @Override
162            public boolean connect(BluetoothDevice device) {
163                return sink.connect(device);
164            }
165
166            @Override
167            public boolean disconnect(BluetoothDevice device) {
168                return sink.disconnect(device);
169            }
170        };
171    }
172
173    private static Profile newProfile(final BluetoothHeadsetClient client) {
174        return new Profile() {
175            @Override
176            public boolean connect(BluetoothDevice device) {
177                return client.connect(device);
178            }
179
180            @Override
181            public boolean disconnect(BluetoothDevice device) {
182                return client.disconnect(device);
183            }
184        };
185    }
186
187    private static Profile newProfile(final BluetoothInputDevice input) {
188        return new Profile() {
189            @Override
190            public boolean connect(BluetoothDevice device) {
191                return input.connect(device);
192            }
193
194            @Override
195            public boolean disconnect(BluetoothDevice device) {
196                return input.disconnect(device);
197            }
198        };
199    }
200
201    private static Profile newProfile(final BluetoothMap map) {
202        return new Profile() {
203            @Override
204            public boolean connect(BluetoothDevice device) {
205                return map.connect(device);
206            }
207
208            @Override
209            public boolean disconnect(BluetoothDevice device) {
210                return map.disconnect(device);
211            }
212        };
213    }
214
215    private static Profile newProfile(final BluetoothPan pan) {
216        return new Profile() {
217            @Override
218            public boolean connect(BluetoothDevice device) {
219                return pan.connect(device);
220            }
221
222            @Override
223            public boolean disconnect(BluetoothDevice device) {
224                return pan.disconnect(device);
225            }
226        };
227    }
228
229    // common abstraction for supported profiles
230    public interface Profile {
231        boolean connect(BluetoothDevice device);
232        boolean disconnect(BluetoothDevice device);
233    }
234}
235