BluetoothA2dp.java revision 41d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.bluetooth; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.SdkConstant; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.SdkConstant.SdkConstantType; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 2341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganeshimport android.os.ParcelUuid; 2462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.os.RemoteException; 2562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.os.ServiceManager; 2662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.server.BluetoothA2dpService; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport java.util.Collections; 3062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport java.util.Arrays; 3162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport java.util.HashMap; 32bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport java.util.HashSet; 3362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport java.util.Set; 3462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth A2DP 3862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh *<p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP 4162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 4262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * the BluetoothA2dp proxy object. 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> Android only supports one connected Bluetooth A2dp device at a time. 4562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Each method is protected with its appropriate permission. 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshpublic final class BluetoothA2dp implements BluetoothProfile { 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "BluetoothA2dp"; 49f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project private static final boolean DBG = false; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 5262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Intent used to broadcast the change in connection state of the A2DP 5362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 5462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 5562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>This intent will have 3 extras: 5662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} - The current state of the profile. 5762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile 5862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. 5962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 6062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 6162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 6262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 6362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 6462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 6562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 6662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 6762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final String ACTION_CONNECTION_STATE_CHANGED = 6862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED"; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 7162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Intent used to broadcast the change in the Playing state of the A2DP 7262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 7362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 7462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>This intent will have 3 extras: 7562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} - The current state of the profile. 7662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile 7762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. 7862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 7962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 8062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING}, 8162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 8262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 8562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final String ACTION_PLAYING_STATE_CHANGED = 8662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED"; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 8962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * A2DP sink device is streaming music. This state can be one of 9062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 9162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #ACTION_PLAYING_STATE_CHANGED} intent. 9262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 9362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final int STATE_PLAYING = 10; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 9662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * A2DP sink device is NOT streaming music. This state can be one of 9762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 9862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #ACTION_PLAYING_STATE_CHANGED} intent. 9962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 10062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final int STATE_NOT_PLAYING = 11; 101bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly 10262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private ServiceListener mServiceListener; 10362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private IBluetoothA2dp mService; 10462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private BluetoothAdapter mAdapter; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a BluetoothA2dp proxy object for interacting with the local 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Bluetooth A2DP service. 10962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /*package*/ BluetoothA2dp(Context mContext, ServiceListener l) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder b = ServiceManager.getService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE); 11362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mServiceListener = l; 11462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mAdapter = BluetoothAdapter.getDefaultAdapter(); 115081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan if (b != null) { 116081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan mService = IBluetoothA2dp.Stub.asInterface(b); 11762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mServiceListener != null) { 11862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mServiceListener.onServiceConnected(BluetoothProfile.A2DP, this); 11962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 120081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan } else { 121081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan Log.w(TAG, "Bluetooth A2DP service not available!"); 122081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan 123081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan // Instead of throwing an exception which prevents people from going 124081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan // into Wireless settings in the emulator. Let it crash later when it is actually used. 125081f58abb7ceb702fdb0b65ff0e0ff70dd265a30Michael Chan mService = null; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 13062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 13162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean connect(BluetoothDevice device) { 13462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("connect(" + device + ")"); 13562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 13662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 13762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 13862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.connect(device); 13962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 14062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 14162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 14262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 14562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 14962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 15062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean disconnect(BluetoothDevice device) { 15362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("disconnect(" + device + ")"); 15462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 15562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 15662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 15762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.disconnect(device); 15862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 15962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 16062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 16162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 16462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 16862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 169f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan */ 17062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public Set<BluetoothDevice> getConnectedDevices() { 17162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("getConnectedDevices()"); 17262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled()) { 17362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 17462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return toDeviceSet(mService.getConnectedDevices()); 17562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 17662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 17762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return toDeviceSet(new BluetoothDevice[0]); 17862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 179f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 18062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 18162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return toDeviceSet(new BluetoothDevice[0]); 182f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 183f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan 18462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 18562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 186f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan */ 18762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public Set<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 18862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("getDevicesMatchingStates()"); 18962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled()) { 19062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 19162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return toDeviceSet(mService.getDevicesMatchingConnectionStates(states)); 19262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 19362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 19462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return toDeviceSet(new BluetoothDevice[0]); 19562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 196f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 19762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 19862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return toDeviceSet(new BluetoothDevice[0]); 199f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 200f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan 20162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 20262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getConnectionState(BluetoothDevice device) { 20562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("getState(" + device + ")"); 20662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() 20762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh && isValidDevice(device)) { 20862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 20962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getConnectionState(device); 21062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 21162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 21262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 21362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 21462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 21562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 21662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 22062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean setPriority(BluetoothDevice device, int priority) { 22462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("setPriority(" + device + ", " + priority + ")"); 22562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() 22662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh && isValidDevice(device)) { 22762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (priority != BluetoothProfile.PRIORITY_OFF && 22862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh priority != BluetoothProfile.PRIORITY_ON) { 22962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 23062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 23162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 23262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.setPriority(device, priority); 23362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 23462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 23562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 23662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 23962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 24362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 244b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh * @hide 245b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh */ 24662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getPriority(BluetoothDevice device) { 24762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("getPriority(" + device + ")"); 24862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() 24962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh && isValidDevice(device)) { 25062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 25162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getPriority(device); 25262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 25362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 25462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return BluetoothProfile.PRIORITY_OFF; 25562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 256b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh } 25762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 25862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return BluetoothProfile.PRIORITY_OFF; 259b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh } 260b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh 26162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 26262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Check if A2DP profile is streaming music. 26362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 26462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} 26562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 26662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device BluetoothDevice device 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 26862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean isA2dpPlaying(BluetoothDevice device) { 26962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() 27062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh && isValidDevice(device)) { 27162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 27262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.isA2dpPlaying(device); 27362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 27462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 27562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 27662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 27962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 28362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Initiate suspend from an A2DP sink. 28462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 28562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> This API will return false in scenarios like the A2DP 28662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * device is not in connected state etc. When this API returns, 28762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * true, it is guaranteed that {@link #ACTION_SINK_STATE_CHANGED} 28862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * intent will be broadcasted with the state. Users can get the 28962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * state of the A2DP device from this intent. 29062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 29162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 29262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 29362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device Remote A2DP sink 29462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @return false on immediate error, 29562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * true otherwise 29662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 29862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean suspendSink(BluetoothDevice device) { 29962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() 30062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh && isValidDevice(device)) { 30162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 30262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.suspendSink(device); 30362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 30462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 30562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 30662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 30962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 31362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Initiate resume from a suspended A2DP sink. 31462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 31562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> This API will return false in scenarios like the A2DP 31662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * device is not in suspended state etc. When this API returns, 31762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * true, it is guaranteed that {@link #ACTION_SINK_STATE_CHANGED} 31862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * intent will be broadcasted with the state. Users can get the 31962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * state of the A2DP device from this intent. 32062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 32162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 32262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 32362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device Remote A2DP sink 32462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @return false on immediate error, 32562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * true otherwise 32662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 32862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean resumeSink(BluetoothDevice device) { 32962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() 33062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh && isValidDevice(device)) { 33162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 33262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.resumeSink(device); 33362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 33462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 33562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 33662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 33962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh /** 34341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * This function checks if the remote device is an AVCRP 34441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * target and thus whether we should send volume keys 34541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * changes or not. 34641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * @hide 34741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh */ 34841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh public boolean shouldSendVolumeKeys(BluetoothDevice device) { 34941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (isEnabled() && isValidDevice(device)) { 35041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh ParcelUuid[] uuids = device.getUuids(); 35141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (uuids == null) return false; 35241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh 35341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh for (ParcelUuid uuid: uuids) { 35441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (BluetoothUuid.isAvrcpTarget(uuid)) { 35541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh return true; 35641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 35741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 35841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 35941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh return false; 36041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 36141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh 36262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 36362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Helper for converting a state to a string. 36462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For debug use only - strings are not internationalized. 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static String stateToString(int state) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (state) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_DISCONNECTED: 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "disconnected"; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_CONNECTING: 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "connecting"; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_CONNECTED: 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "connected"; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_DISCONNECTING: 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "disconnecting"; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_PLAYING: 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "playing"; 38062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh case STATE_NOT_PLAYING: 38162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return "not playing"; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "<unknown state " + state + ">"; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 386f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project 38762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private boolean isEnabled() { 38862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 38962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 39062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 39162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 39262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private boolean isValidDevice(BluetoothDevice device) { 39362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (device == null) return false; 39462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 39562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 39662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 39762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 39862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 39962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private Set<BluetoothDevice> toDeviceSet(BluetoothDevice[] devices) { 40062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return Collections.unmodifiableSet( 40162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh new HashSet<BluetoothDevice>(Arrays.asList(devices))); 40262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 40362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 404f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project private static void log(String msg) { 40562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.d(TAG, msg); 406f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 408