Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: webrtc/examples/androidapp/src/org/appspot/apprtc/AppRTCBluetoothManager.java

Issue 2501983002: Adds basic Bluetooth support to AppRTCMobile (Closed)
Patch Set: Finalized the test suite. Now contains seven tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 package org.appspot.apprtc;
12
13 import org.appspot.apprtc.util.AppRTCUtils;
14
15 import android.bluetooth.BluetoothAdapter;
16 import android.bluetooth.BluetoothDevice;
17 import android.bluetooth.BluetoothHeadset;
18 import android.bluetooth.BluetoothProfile;
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.pm.PackageManager;
24 import android.media.AudioManager;
25 import android.os.Handler;
26 import android.os.Looper;
27 import android.os.Process;
28 import android.util.Log;
29
30 import org.webrtc.ThreadUtils;
31
32 import java.util.List;
33 import java.util.Set;
34
35 /**
36 * AppRTCProximitySensor manages functions related to Bluetoth devices in the
37 * AppRTC demo.
38 */
39 public class AppRTCBluetoothManager {
40 private static final String TAG = "AppRTCBluetoothManager";
41
42 // Timeout interval for starting or stopping audio to a Bluetooth SCO device.
43 private static final int BLUETOOTH_SCO_TIMEOUT_MS = 4000;
44 // Maximum number of SCO connection attempts.
45 private static final int MAX_SCO_CONNECTION_ATTEMPTS = 2;
46
47 // Bluetooth connection state.
48 public enum State {
49 // Bluetooth is not available; no adapter or Bluetooth is off.
50 UNINITIALIZED,
51 // Bluetooth error happened when trying to start Bluetooth.
52 ERROR,
53 // Bluetooth proxy object for the Headset profile exists, but no connected h eadset devices,
54 // SCO is not started or disconnected.
55 HEADSET_UNAVAILABLE,
56 // Bluetooth proxy object for the Headset profile connected, connected Bluet ooth headset
57 // present, but SCO is not started or disconnected.
58 HEADSET_AVAILABLE,
59 // Bluetooth audio SCO connection with remote device is closing.
60 SCO_DISCONNECTING,
61 // Bluetooth audio SCO connection with remote device is initiated.
62 SCO_CONNECTING,
63 // Bluetooth audio SCO connection with remote device is established.
64 SCO_CONNECTED
65 }
66
67 private final ThreadUtils.ThreadChecker threadChecker = new ThreadUtils.Thread Checker();
68
69 private final Context apprtcContext;
70 private final AppRTCAudioManager apprtcAudioManager;
71 private final AudioManager audioManager;
72 private final Handler handler;
73
74 int scoConnectionAttempts;
75 private State bluetoothState;
76 private final BluetoothProfile.ServiceListener bluetoothServiceListener;
77 private BluetoothAdapter bluetoothAdapter;
78 private BluetoothHeadset bluetoothHeadset;
79 private BluetoothDevice bluetoothDevice;
80 private final BroadcastReceiver bluetoothHeadsetReceiver;
81
82 // Runs when the Bluetooth timeout expires. We use that timeout after calling
83 // startScoAudio() or stopScoAudio() because we're not guaranteed to get a
84 // callback after those calls.
85 private final Runnable bluetoothTimeoutRunnable = new Runnable() {
86 @Override
87 public void run() {
88 bluetoothTimeout();
89 }
90 };
91
92 /**
93 * Implementation of an interface that notifies BluetoothProfile IPC clients w hen they have been
94 * connected to or disconnected from the service.
95 */
96 private class BluetoothServiceListener implements BluetoothProfile.ServiceList ener {
97 @Override
98 // Called to notify the client when the proxy object has been connected to t he service.
99 // Once we have the profile proxy object, we can use it to monitor the state of the
100 // connection and perform other operations that are relevant to the headset profile.
101 public void onServiceConnected(int profile, BluetoothProfile proxy) {
102 if (profile != BluetoothProfile.HEADSET || bluetoothState == State.UNINITI ALIZED) {
103 return;
104 }
105 Log.d(TAG, "BluetoothServiceListener.onServiceConnected: BT state=" + blue toothState);
106 // Android only supports one connected Bluetooth Headset at a time.
107 bluetoothHeadset = (BluetoothHeadset) proxy;
108 updateAudioDeviceState();
109 Log.d(TAG, "onServiceConnected done: BT state=" + bluetoothState);
110 }
111
112 @Override
113 /** Notifies the client when the proxy object has been disconnected from the service. */
114 public void onServiceDisconnected(int profile) {
115 if (profile != BluetoothProfile.HEADSET || bluetoothState == State.UNINITI ALIZED) {
116 return;
117 }
118 Log.d(TAG, "BluetoothServiceListener.onServiceDisconnected: BT state=" + b luetoothState);
119 stopScoAudio();
120 bluetoothHeadset = null;
121 bluetoothDevice = null;
122 bluetoothState = State.HEADSET_UNAVAILABLE;
123 updateAudioDeviceState();
124 Log.d(TAG, "onServiceDisconnected done: BT state=" + bluetoothState);
125 }
126 }
127
128 // Intent broadcast receiver which handles changes in Bluetooth device availab ility.
129 // Detects headset changes and Bluetooth SCO state changes.
130 private class BluetoothHeadsetBroadcastReceiver extends BroadcastReceiver {
131 @Override
132 public void onReceive(Context context, Intent intent) {
133 if (bluetoothState == State.UNINITIALIZED) {
134 return;
135 }
136 final String action = intent.getAction();
137 // Change in connection state of the Headset profile. Note that the
138 // change does not tell us anything about whether we're streaming
139 // audio to BT over SCO. Typically received when user turns on a BT
140 // headset while audio is active using another audio device.
141 if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
142 final int state =
143 intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.ST ATE_DISCONNECTED);
144 Log.d(TAG, "BluetoothHeadsetBroadcastReceiver.onReceive: "
145 + "a=ACTION_CONNECTION_STATE_CHANGED, "
146 + "s=" + stateToString(state) + ", "
147 + "sb=" + isInitialStickyBroadcast() + ", "
148 + "BT state: " + bluetoothState);
149 if (state == BluetoothHeadset.STATE_CONNECTED) {
150 scoConnectionAttempts = 0;
151 updateAudioDeviceState();
152 } else if (state == BluetoothHeadset.STATE_CONNECTING) {
153 // No action needed.
154 } else if (state == BluetoothHeadset.STATE_DISCONNECTING) {
155 // No action needed.
156 } else if (state == BluetoothHeadset.STATE_DISCONNECTED) {
157 // Bluetooth is probably powered off during the call.
158 stopScoAudio();
159 updateAudioDeviceState();
160 }
161 // Change in the audio (SCO) connection state of the Headset profile.
162 // Typically received after call to startScoAudio() has finalized.
163 } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
164 final int state = intent.getIntExtra(
165 BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNEC TED);
166 Log.d(TAG, "BluetoothHeadsetBroadcastReceiver.onReceive: "
167 + "a=ACTION_AUDIO_STATE_CHANGED, "
168 + "s=" + stateToString(state) + ", "
169 + "sb=" + isInitialStickyBroadcast() + ", "
170 + "BT state: " + bluetoothState);
171 if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
172 cancelTimer();
173 if (bluetoothState == State.SCO_CONNECTING) {
174 Log.d(TAG, "+++ Bluetooth audio SCO is now connected");
175 bluetoothState = State.SCO_CONNECTED;
176 scoConnectionAttempts = 0;
177 updateAudioDeviceState();
178 } else {
179 Log.w(TAG, "Unexpected state BluetoothHeadset.STATE_AUDIO_CONNECTED" );
180 }
181 } else if (state == BluetoothHeadset.STATE_AUDIO_CONNECTING) {
182 Log.d(TAG, "+++ Bluetooth audio SCO is now connecting...");
183 } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
184 Log.d(TAG, "+++ Bluetooth audio SCO is now disconnected");
185 if (isInitialStickyBroadcast()) {
186 Log.d(TAG, "Ignore STATE_AUDIO_DISCONNECTED initial sticky broadcast .");
187 return;
188 }
189 updateAudioDeviceState();
190 }
191 }
192 Log.d(TAG, "onReceive done: BT state=" + bluetoothState);
193 }
194 };
195
196 /** Construction. */
197 static AppRTCBluetoothManager create(Context context, AppRTCAudioManager audio Manager) {
198 Log.d(TAG, "create" + AppRTCUtils.getThreadInfo());
199 return new AppRTCBluetoothManager(context, audioManager);
200 }
201
202 protected AppRTCBluetoothManager(Context context, AppRTCAudioManager audioMana ger) {
203 Log.d(TAG, "ctor");
204 ThreadUtils.checkIsOnMainThread();
magjed_webrtc 2016/12/10 19:34:45 Use threadChecker.checkIsOnValidThread() instead.
henrika_webrtc 2016/12/12 14:13:25 Done.
205 apprtcContext = context;
206 apprtcAudioManager = audioManager;
207 this.audioManager = getAudioManager(context);
208 bluetoothState = State.UNINITIALIZED;
209 bluetoothServiceListener = new BluetoothServiceListener();
210 bluetoothHeadsetReceiver = new BluetoothHeadsetBroadcastReceiver();
211 handler = new Handler(Looper.getMainLooper());
212 }
213
214 /** Returns the internal state. */
215 public State getState() {
216 threadChecker.checkIsOnValidThread();
217 return bluetoothState;
218 }
219
220 /**
221 * Activates components required to detect Bluetooth devices and to enable
222 * BT SCO (audio is routed via BT SCO) for the headset profile. The end
223 * state will be HEADSET_UNAVAILABLE but a state machine has started which
224 * will start a state change sequence where the final outcome depends on
225 * if/when the BT headset is enabled.
226 * Example of state change sequence when start() is called while BT device
227 * is connected and enabled:
228 * UNINITIALIZED --> HEADSET_UNAVAILABLE --> HEADSET_AVAILABLE -->
229 * SCO_CONNECTING --> SCO_CONNECTED <==> audio is now routed via BT SCO.
230 * Note that the AppRTCAudioManager is also involved in driving this state
231 * change.
232 */
233 public void start() {
234 threadChecker.checkIsOnValidThread();
235 Log.d(TAG, "start");
236 if (!hasPermission(apprtcContext, android.Manifest.permission.BLUETOOTH)) {
237 Log.w(TAG, "Process (pid=" + Process.myPid() + ") lacks BLUETOOTH permissi on");
238 return;
239 }
240 if (bluetoothState != State.UNINITIALIZED) {
241 Log.w(TAG, "Invalid BT state");
242 return;
243 }
244 bluetoothHeadset = null;
245 bluetoothDevice = null;
246 scoConnectionAttempts = 0;
247 // Get a handle to the default local Bluetooth adapter.
248 bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
249 if (bluetoothAdapter == null) {
250 Log.w(TAG, "Device does not support Bluetooth");
251 return;
252 }
253 // Ensure that the device supports use of BT SCO audio for off call use case s.
254 if (!audioManager.isBluetoothScoAvailableOffCall()) {
255 Log.e(TAG, "Bluetooth SCO audio is not available off call");
256 return;
257 }
258 logBluetoothAdapterInfo(bluetoothAdapter);
259 // Establish a connection to the HEADSET profile (includes both Bluetooth He adset and
260 // Hands-Free) proxy object and install a listener.
261 if (!getBluetoothProfileProxy(
262 apprtcContext, bluetoothServiceListener, BluetoothProfile.HEADSET)) {
263 Log.e(TAG, "BluetoothAdapter.getProfileProxy(HEADSET) failed");
264 return;
265 }
266 // Register receivers for BluetoothHeadset change notifications.
267 IntentFilter bluetoothHeadsetFilter = new IntentFilter();
268 // Register receiver for change in connection state of the Headset profile.
269 bluetoothHeadsetFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CH ANGED);
270 // Register receiver for change in audio connection state of the Headset pro file.
271 bluetoothHeadsetFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED );
272 registerReceiver(bluetoothHeadsetReceiver, bluetoothHeadsetFilter);
273 Log.d(TAG, "HEADSET profile state: "
274 + stateToString(bluetoothAdapter.getProfileConnectionState(Bluetooth Profile.HEADSET)));
275 Log.d(TAG, "Bluetooth proxy for headset profile has started");
276 bluetoothState = State.HEADSET_UNAVAILABLE;
277 Log.d(TAG, "start done: BT state=" + bluetoothState);
278 }
279
280 /** Stops and closes all components related to Bluetooth audio. */
281 public void stop() {
282 threadChecker.checkIsOnValidThread();
283 unregisterReceiver(bluetoothHeadsetReceiver);
284 Log.d(TAG, "stop: BT state=" + bluetoothState);
285 if (bluetoothAdapter != null) {
286 // Stop BT SCO connection with remote device if needed.
287 stopScoAudio();
288 // Close down remaining BT resources.
289 if (bluetoothState != State.UNINITIALIZED) {
290 cancelTimer();
291 if (bluetoothHeadset != null) {
292 bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, bluetooth Headset);
293 bluetoothHeadset = null;
294 }
295 bluetoothAdapter = null;
296 bluetoothDevice = null;
297 bluetoothState = State.UNINITIALIZED;
298 }
299 }
300 Log.d(TAG, "stop done: BT state=" + bluetoothState);
301 }
302
303 /**
304 * Starts Bluetooth SCO connection with remote device.
305 * Note that the phone application always has the priority on the usage of the SCO connection
306 * for telephony. If this method is called while the phone is in call it will be ignored.
307 * Similarly, if a call is received or sent while an application is using the SCO connection,
308 * the connection will be lost for the application and NOT returned automatica lly when the call
309 * ends. Also note that: up to and including API version JELLY_BEAN_MR1, this method initiates a
310 * virtual voice call to the Bluetooth headset. After API version JELLY_BEAN_M R2 only a raw SCO
311 * audio connection is established.
312 * TODO(henrika): should we add support for virtual voice call to BT headset a lso for JBMR2 and
313 * higher. It might be required to initiates a virtual voice call since many d evices do not
314 * accept SCO audio without a "call".
315 */
316 public boolean startScoAudio() {
317 threadChecker.checkIsOnValidThread();
318 Log.d(TAG, "startSco: BT state=" + bluetoothState + ", "
319 + "attempts: " + scoConnectionAttempts + ", "
320 + "SCO is on: " + isScoOn());
321 if (scoConnectionAttempts >= MAX_SCO_CONNECTION_ATTEMPTS) {
322 Log.e(TAG, "BT SCO connection fails - no more attempts");
323 return false;
324 }
325 if (bluetoothState != State.HEADSET_AVAILABLE) {
326 Log.e(TAG, "BT SCO connection fails - no headset available");
327 return false;
328 }
329 // Start BT SCO channel and wait for ACTION_AUDIO_STATE_CHANGED.
330 Log.d(TAG, "Starting Bluetooth SCO and waits for ACTION_AUDIO_STATE_CHANGED. ..");
331 // The SCO connection establishment can take several seconds, hence we canno t rely on the
332 // connection to be available when the method returns but instead register t o receive the
333 // intent ACTION_SCO_AUDIO_STATE_UPDATED and wait for the state to be SCO_AU DIO_STATE_CONNECTED.
334 bluetoothState = State.SCO_CONNECTING;
335 audioManager.startBluetoothSco();
336 scoConnectionAttempts++;
337 startTimer();
338 Log.d(TAG, "startScoAudio done: BT state=" + bluetoothState);
339 return true;
340 }
341
342 /** Stops Bluetooth SCO connection with remote device. */
343 public void stopScoAudio() {
344 threadChecker.checkIsOnValidThread();
345 Log.d(TAG, "stopScoAudio: BT state=" + bluetoothState + ", "
346 + "SCO is on: " + isScoOn());
347 if (bluetoothState != State.SCO_CONNECTING && bluetoothState != State.SCO_CO NNECTED) {
348 return;
349 }
350 cancelTimer();
351 audioManager.stopBluetoothSco();
352 bluetoothState = State.SCO_DISCONNECTING;
353 Log.d(TAG, "stopScoAudio done: BT state=" + bluetoothState);
354 }
355
356 /**
357 * Use the BluetoothHeadset proxy object (controls the Bluetooth Headset
358 * Service via IPC) to update the list of connected devices for the HEADSET
359 * profile. The internal state will change to HEADSET_UNAVAILABLE or to
360 * HEADSET_AVAILABLE and |bluetoothDevice| will be mapped to the connected
361 * device if available.
362 */
363 public void updateDevice() {
364 if (bluetoothState == State.UNINITIALIZED || bluetoothHeadset == null) {
365 return;
366 }
367 Log.d(TAG, "updateDevice");
368 // Get connected devices for the headset profile. Returns the set of
369 // devices which are in state STATE_CONNECTED. The BluetoothDevice class
370 // is just a thin wrapper for a Bluetooth hardware address.
371 List<BluetoothDevice> devices = bluetoothHeadset.getConnectedDevices();
372 if (devices.size() == 0) {
magjed_webrtc 2016/12/10 19:34:44 nit: Use devices.isEmpty() instead.
henrika_webrtc 2016/12/12 14:13:25 Done.
373 bluetoothDevice = null;
374 } else {
375 // Always use first device is list. Android only supports one device.
376 bluetoothDevice = devices.get(0);
377 }
378 if (bluetoothDevice == null) {
magjed_webrtc 2016/12/10 19:34:44 Join this if-statement with the one above since th
henrika_webrtc 2016/12/12 14:13:25 Thanks. Done!
379 bluetoothState = State.HEADSET_UNAVAILABLE;
380 Log.d(TAG, "No connected bluetooth headset");
381 } else {
382 bluetoothState = State.HEADSET_AVAILABLE;
383 Log.d(TAG, "Connected bluetooth headset: "
384 + "name=" + bluetoothDevice.getName() + ", "
385 + "state=" + stateToString(bluetoothHeadset.getConnectionState(blu etoothDevice))
386 + ", SCO audio=" + bluetoothHeadset.isAudioConnected(bluetoothDevi ce));
387 }
388 Log.d(TAG, "updateDevice done: BT state=" + bluetoothState);
389 }
390
391 /**
392 * Stubs for test mocks.
393 */
394 protected AudioManager getAudioManager(Context context) {
395 return (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
396 }
397
398 protected void registerReceiver(BroadcastReceiver receiver, IntentFilter filte r) {
399 apprtcContext.registerReceiver(receiver, filter);
400 }
401
402 protected void unregisterReceiver(BroadcastReceiver receiver) {
403 apprtcContext.unregisterReceiver(receiver);
404 }
405
406 protected boolean getBluetoothProfileProxy(
407 Context context, BluetoothProfile.ServiceListener listener, int profile) {
408 return bluetoothAdapter.getProfileProxy(context, listener, profile);
409 }
410
411 protected boolean hasPermission(Context context, String permission) {
412 return apprtcContext.checkPermission(permission, Process.myPid(), Process.my Uid())
413 == PackageManager.PERMISSION_GRANTED;
414 }
415
416 /** Logs the state of the local Bluetooth adapter. */
417 protected void logBluetoothAdapterInfo(BluetoothAdapter localAdapter) {
418 Log.d(TAG, "BluetoothAdapter: "
419 + "enabled=" + localAdapter.isEnabled() + ", "
420 + "state=" + stateToString(localAdapter.getState()) + ", "
421 + "name=" + localAdapter.getName() + ", "
422 + "address=" + localAdapter.getAddress());
423 // Log the set of BluetoothDevice objects that are bonded (paired) to the lo cal adapter.
424 Set<BluetoothDevice> pairedDevices = localAdapter.getBondedDevices();
425 if (pairedDevices.size() > 0) {
magjed_webrtc 2016/12/10 19:34:45 nit: !pairedDevices.isEmpty()
henrika_webrtc 2016/12/12 14:13:25 Done.
426 Log.d(TAG, "paired devices:");
427 for (BluetoothDevice device : pairedDevices) {
428 Log.d(TAG, " name=" + device.getName() + ", address=" + device.getAddres s());
429 }
430 }
431 }
432
433 /** Ensures that the audio manager updates its list of available audio devices . */
434 private void updateAudioDeviceState() {
435 threadChecker.checkIsOnValidThread();
436 Log.d(TAG, "updateAudioDeviceState");
437 apprtcAudioManager.updateAudioDeviceState();
438 }
439
440 /** Starts timer which times out after BLUETOOTH_SCO_TIMEOUT_MS milliseconds. */
441 private void startTimer() {
442 threadChecker.checkIsOnValidThread();
443 Log.d(TAG, "startTimer");
444 handler.postDelayed(bluetoothTimeoutRunnable, BLUETOOTH_SCO_TIMEOUT_MS);
445 }
446
447 /** Cancels any outstanding timer tasks. */
448 private void cancelTimer() {
449 threadChecker.checkIsOnValidThread();
450 Log.d(TAG, "cancelTimer");
451 handler.removeCallbacks(bluetoothTimeoutRunnable);
452 }
453
454 /**
455 * Called when start of the BT SCO channel takes too long time. Usually
456 * happens when the BT device has been turned on during an ongoing call.
457 */
458 private void bluetoothTimeout() {
459 threadChecker.checkIsOnValidThread();
460 if (bluetoothState == State.UNINITIALIZED || bluetoothHeadset == null) {
461 return;
462 }
463 Log.d(TAG, "bluetoothTimeout: BT state=" + bluetoothState + ", "
464 + "attempts: " + scoConnectionAttempts + ", "
465 + "SCO is on: " + isScoOn());
466 if (bluetoothState != State.SCO_CONNECTING) {
467 return;
468 }
469 // Bluetooth SCO should be connecting; check the latest result.
470 boolean scoConnected = false;
471 List<BluetoothDevice> devices = bluetoothHeadset.getConnectedDevices();
472 if (devices.size() > 0) {
473 bluetoothDevice = devices.get(0);
474 if (bluetoothHeadset.isAudioConnected(bluetoothDevice)) {
475 Log.d(TAG, "SCO connected with " + bluetoothDevice.getName());
476 scoConnected = true;
477 } else {
478 Log.d(TAG, "SCO is not connected with " + bluetoothDevice.getName());
479 }
480 }
481 if (scoConnected) {
482 // We thought BT had timed out, but it's actually on; updating state.
483 bluetoothState = State.SCO_CONNECTED;
484 scoConnectionAttempts = 0;
485 updateAudioDeviceState();
magjed_webrtc 2016/12/10 19:34:44 Move this after the if-statement since you do it l
henrika_webrtc 2016/12/12 14:13:25 Done.
486 } else {
487 // Give up and "cancel" our request by calling stopBluetoothSco().
488 Log.w(TAG, "BT failed to connect after timeout");
489 stopScoAudio();
490 updateAudioDeviceState();
491 }
492 Log.d(TAG, "bluetoothTimeout done: BT state=" + bluetoothState);
493 }
494
495 /** Checks whether audio uses Bluetooth SCO. */
496 private boolean isScoOn() {
497 return audioManager.isBluetoothScoOn();
magjed_webrtc 2016/12/10 19:34:44 I personally would just inline audioManager.isBlue
henrika_webrtc 2016/12/12 14:13:25 ACK, used same style in AudioManager. Keeping as i
498 }
499
500 /** Converts BluetoothAdapter states into local string representations. */
501 private String stateToString(int state) {
502 String stateString;
503 switch (state) {
504 case BluetoothAdapter.STATE_DISCONNECTED:
505 // The profile is in disconnected state.
magjed_webrtc 2016/12/10 19:34:45 Remove |stateString| and just do return "DISCONNEC
henrika_webrtc 2016/12/12 14:13:25 Done.
506 stateString = "DISCONNECTED";
507 break;
508 case BluetoothAdapter.STATE_CONNECTED:
509 // The profile is in connected state.
magjed_webrtc 2016/12/10 19:34:45 Many of these comments provide no extra informatio
henrika_webrtc 2016/12/12 14:13:25 Agree. Removed.
510 stateString = "CONNECTED";
511 break;
512 case BluetoothAdapter.STATE_CONNECTING:
513 // The profile is in connecting state.
514 stateString = "CONNECTING";
515 break;
516 case BluetoothAdapter.STATE_DISCONNECTING:
517 // The profile is in disconnecting state.
518 stateString = "DISCONNECTING";
519 break;
520 case BluetoothAdapter.STATE_OFF:
521 // Indicates the local Bluetooth adapter is off.
522 stateString = "OFF";
523 break;
524 case BluetoothAdapter.STATE_ON:
525 // Indicates the local Bluetooth adapter is on, and ready for use.
526 stateString = "ON";
527 break;
528 case BluetoothAdapter.STATE_TURNING_OFF:
529 // Indicates the local Bluetooth adapter is turning off. Local clients s hould immediately
530 // attempt graceful disconnection of any remote links.
531 stateString = "TURNING_OFF";
532 break;
533 case BluetoothAdapter.STATE_TURNING_ON:
534 // Indicates the local Bluetooth adapter is turning on. However local cl ients should wait
535 // for STATE_ON before attempting to use the adapter.
536 stateString = "TURNING_ON";
537 break;
538 default:
539 stateString = "INVALID";
540 break;
541 }
542 return stateString;
543 }
544 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698