Merge "Merge changes from topic "bt-fix-checkstyle-errors" am: 838ab94a0f am: 8ae5462199 am: 24ad4cfc48" into oc-mr1-dev-plus-aosp

am: 450c6035b5

Change-Id: I4ce490de222eb4e76f40e2989473a9ad37f70d7c
This commit is contained in:
Jack He
2017-08-24 22:41:41 +00:00
committed by android-build-merger
76 changed files with 4643 additions and 4265 deletions

View File

@@ -42,7 +42,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* This class provides the public APIs to control the Bluetooth A2DP
* profile.
*
*<p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP
* <p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP
* Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
* the BluetoothA2dp proxy object.
*
@@ -60,9 +60,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -74,7 +74,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
/**
* Intent used to broadcast the change in the Playing state of the A2DP
@@ -82,9 +82,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -95,12 +95,12 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PLAYING_STATE_CHANGED =
"android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
"android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
/** @hide */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_AVRCP_CONNECTION_STATE_CHANGED =
"android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED";
"android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED";
/**
* Intent used to broadcast the change in the Audio Codec state of the
@@ -108,9 +108,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* <p>This intent will have 2 extras:
* <ul>
* <li> {@link BluetoothCodecStatus#EXTRA_CODEC_STATUS} - The codec status. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
* connected, otherwise it is not included.</li>
* <li> {@link BluetoothCodecStatus#EXTRA_CODEC_STATUS} - The codec status. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
* connected, otherwise it is not included.</li>
* </ul>
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
@@ -120,61 +120,74 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CODEC_CONFIG_CHANGED =
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
/**
* A2DP sink device is streaming music. This state can be one of
* {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
* {@link #ACTION_PLAYING_STATE_CHANGED} intent.
*/
public static final int STATE_PLAYING = 10;
public static final int STATE_PLAYING = 10;
/**
* A2DP sink device is NOT streaming music. This state can be one of
* {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
* {@link #ACTION_PLAYING_STATE_CHANGED} intent.
*/
public static final int STATE_NOT_PLAYING = 11;
public static final int STATE_NOT_PLAYING = 11;
/**
* We don't have a stored preference for whether or not the given A2DP sink device supports
* optional codecs.
* @hide */
*
* @hide
*/
public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1;
/**
* The given A2DP sink device does not support optional codecs.
* @hide */
*
* @hide
*/
public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0;
/**
* The given A2DP sink device does support optional codecs.
* @hide */
*
* @hide
*/
public static final int OPTIONAL_CODECS_SUPPORTED = 1;
/**
* We don't have a stored preference for whether optional codecs should be enabled or disabled
* for the given A2DP device.
* @hide */
*
* @hide
*/
public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1;
/**
* Optional codecs should be disabled for the given A2DP device.
* @hide */
*
* @hide
*/
public static final int OPTIONAL_CODECS_PREF_DISABLED = 0;
/**
* Optional codecs should be enabled for the given A2DP device.
* @hide */
* Optional codecs should be enabled for the given A2DP device.
*
* @hide
*/
public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;
private Context mContext;
private ServiceListener mServiceListener;
private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
@GuardedBy("mServiceLock") private IBluetoothA2dp mService;
@GuardedBy("mServiceLock")
private IBluetoothA2dp mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
@@ -193,21 +206,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
mServiceLock.readLock().lock();
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
} finally {
mServiceLock.readLock().unlock();
}
}
}
};
};
/**
* Create a BluetoothA2dp proxy object for interacting with the local
* Bluetooth A2DP service.
*
*/
/*package*/ BluetoothA2dp(Context context, ServiceListener l) {
mContext = context;
@@ -218,7 +231,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -244,7 +257,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -261,10 +274,12 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
}
@Override
public void finalize() {
// The empty finalize needs to be kept or the
// cts signature tests would fail.
}
/**
* Initiate connection to a profile of the remote bluetooth device.
*
@@ -283,16 +298,14 @@ public final class BluetoothA2dp implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
try {
mServiceLock.readLock().lock();
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
return mService.connect(device);
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -327,16 +340,14 @@ public final class BluetoothA2dp implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
try {
mServiceLock.readLock().lock();
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
return mService.disconnect(device);
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -352,6 +363,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
try {
@@ -372,6 +384,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
try {
@@ -392,12 +405,13 @@ public final class BluetoothA2dp implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
try {
mServiceLock.readLock().lock();
if (mService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
return mService.getConnectionState(device);
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -414,7 +428,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* Set priority of the profile
*
* <p> The device should already be paired.
* Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
* Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
* {@link #PRIORITY_OFF},
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
@@ -430,9 +444,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
mServiceLock.readLock().lock();
if (mService != null && isEnabled()
&& isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON) {
&& isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
return mService.setPriority(device, priority);
@@ -464,7 +478,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
mServiceLock.readLock().lock();
if (mService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
return mService.getPriority(device);
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -560,7 +574,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
mServiceLock.readLock().lock();
if (mService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
return mService.isA2dpPlaying(device);
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -577,6 +591,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* This function checks if the remote device is an AVCRP
* target and thus whether we should send volume keys
* changes or not.
*
* @hide
*/
public boolean shouldSendVolumeKeys(BluetoothDevice device) {
@@ -584,7 +599,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
ParcelUuid[] uuids = device.getUuids();
if (uuids == null) return false;
for (ParcelUuid uuid: uuids) {
for (ParcelUuid uuid : uuids) {
if (BluetoothUuid.isAvrcpTarget(uuid)) {
return true;
}
@@ -691,8 +706,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @param device The device to check
* @return one of OPTIONAL_CODECS_SUPPORT_UNKNOWN, OPTIONAL_CODECS_NOT_SUPPORTED, or
* OPTIONAL_CODECS_SUPPORTED.
*
* OPTIONAL_CODECS_SUPPORTED.
* @hide
*/
public int supportsOptionalCodecs(BluetoothDevice device) {
@@ -716,8 +730,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @param device The device in question.
* @return one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
* OPTIONAL_CODECS_PREF_DISABLED.
*
* OPTIONAL_CODECS_PREF_DISABLED.
* @hide
*/
public int getOptionalCodecsEnabled(BluetoothDevice device) {
@@ -741,15 +754,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
*
* @param device The device to set this preference for.
* @param value Whether the optional codecs should be enabled for this device. This should be
* one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
* OPTIONAL_CODECS_PREF_DISABLED.
* one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
* OPTIONAL_CODECS_PREF_DISABLED.
* @hide
*/
public void setOptionalCodecsEnabled(BluetoothDevice device, int value) {
try {
if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN &&
value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED &&
value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value);
return;
}
@@ -772,24 +785,25 @@ public final class BluetoothA2dp implements BluetoothProfile {
* Helper for converting a state to a string.
*
* For debug use only - strings are not internationalized.
*
* @hide
*/
public static String stateToString(int state) {
switch (state) {
case STATE_DISCONNECTED:
return "disconnected";
case STATE_CONNECTING:
return "connecting";
case STATE_CONNECTED:
return "connected";
case STATE_DISCONNECTING:
return "disconnecting";
case STATE_PLAYING:
return "playing";
case STATE_NOT_PLAYING:
return "not playing";
default:
return "<unknown state " + state + ">";
case STATE_DISCONNECTED:
return "disconnected";
case STATE_CONNECTING:
return "connecting";
case STATE_CONNECTED:
return "connected";
case STATE_DISCONNECTING:
return "disconnecting";
case STATE_PLAYING:
return "playing";
case STATE_NOT_PLAYING:
return "not playing";
default:
return "<unknown state " + state + ">";
}
}
@@ -807,6 +821,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
try {
@@ -822,18 +837,18 @@ public final class BluetoothA2dp implements BluetoothProfile {
};
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
}
private static void log(String msg) {
Log.d(TAG, msg);
Log.d(TAG, msg);
}
}

View File

@@ -32,7 +32,7 @@ import java.util.List;
* This class provides the public APIs to control the Bluetooth A2DP Sink
* profile.
*
*<p>BluetoothA2dpSink is a proxy object for controlling the Bluetooth A2DP Sink
* <p>BluetoothA2dpSink is a proxy object for controlling the Bluetooth A2DP Sink
* Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
* the BluetoothA2dpSink proxy object.
*
@@ -49,9 +49,9 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -62,7 +62,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* receive.
*/
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
/**
* Intent used to broadcast the change in the Playing state of the A2DP Sink
@@ -70,9 +70,9 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -82,21 +82,21 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* receive.
*/
public static final String ACTION_PLAYING_STATE_CHANGED =
"android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED";
"android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED";
/**
* A2DP sink device is streaming music. This state can be one of
* {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
* {@link #ACTION_PLAYING_STATE_CHANGED} intent.
*/
public static final int STATE_PLAYING = 10;
public static final int STATE_PLAYING = 10;
/**
* A2DP sink device is NOT streaming music. This state can be one of
* {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
* {@link #ACTION_PLAYING_STATE_CHANGED} intent.
*/
public static final int STATE_NOT_PLAYING = 11;
public static final int STATE_NOT_PLAYING = 11;
/**
* Intent used to broadcast the change in the Playing state of the A2DP Sink
@@ -104,15 +104,15 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_AUDIO_CONFIG} - The audio configuration for the remote device. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_AUDIO_CONFIG} - The audio configuration for the remote device. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
* receive.
*/
public static final String ACTION_AUDIO_CONFIG_CHANGED =
"android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED";
"android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED";
/**
* Extra for the {@link #ACTION_AUDIO_CONFIG_CHANGED} intent.
@@ -120,46 +120,46 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* This extra represents the current audio configuration of the A2DP source device.
* {@see BluetoothAudioConfig}
*/
public static final String EXTRA_AUDIO_CONFIG
= "android.bluetooth.a2dp-sink.profile.extra.AUDIO_CONFIG";
public static final String EXTRA_AUDIO_CONFIG =
"android.bluetooth.a2dp-sink.profile.extra.AUDIO_CONFIG";
private Context mContext;
private ServiceListener mServiceListener;
private IBluetoothA2dpSink mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
* Create a BluetoothA2dp proxy object for interacting with the local
* Bluetooth A2DP service.
*
*/
/*package*/ BluetoothA2dpSink(Context context, ServiceListener l) {
mContext = context;
@@ -170,7 +170,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -196,7 +196,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -206,15 +206,17 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
@Override
public void finalize() {
close();
}
/**
* Initiate connection to a profile of the remote bluetooth device.
*
@@ -233,14 +235,12 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.connect(device);
} catch (RemoteException e) {
@@ -274,14 +274,12 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.disconnect(device);
} catch (RemoteException e) {
@@ -296,6 +294,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
if (mService != null && isEnabled()) {
@@ -313,6 +312,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
if (mService != null && isEnabled()) {
@@ -330,10 +330,11 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
if (mService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
try {
return mService.getConnectionState(device);
} catch (RemoteException e) {
@@ -356,10 +357,10 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*
* {@see BluetoothAudioConfig}
*/
public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
if (VDBG) log("getAudioConfig(" + device + ")");
if (mService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
try {
return mService.getAudioConfig(device);
} catch (RemoteException e) {
@@ -375,7 +376,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* Set priority of the profile
*
* <p> The device should already be paired.
* Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
* Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
* {@link #PRIORITY_OFF},
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
@@ -389,20 +390,20 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
if (mService != null && isEnabled()
&& isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON){
&& isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
return mService.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
return false;
}
/**
@@ -421,7 +422,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
try {
return mService.getPriority(device);
} catch (RemoteException e) {
@@ -442,7 +443,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*/
public boolean isA2dpPlaying(BluetoothDevice device) {
if (mService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
try {
return mService.isA2dpPlaying(device);
} catch (RemoteException e) {
@@ -458,24 +459,25 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* Helper for converting a state to a string.
*
* For debug use only - strings are not internationalized.
*
* @hide
*/
public static String stateToString(int state) {
switch (state) {
case STATE_DISCONNECTED:
return "disconnected";
case STATE_CONNECTING:
return "connecting";
case STATE_CONNECTED:
return "connected";
case STATE_DISCONNECTING:
return "disconnecting";
case STATE_PLAYING:
return "playing";
case STATE_NOT_PLAYING:
return "not playing";
default:
return "<unknown state " + state + ">";
case STATE_DISCONNECTED:
return "disconnected";
case STATE_CONNECTING:
return "connecting";
case STATE_CONNECTED:
return "connected";
case STATE_DISCONNECTING:
return "disconnecting";
case STATE_PLAYING:
return "playing";
case STATE_NOT_PLAYING:
return "not playing";
default:
return "<unknown state " + state + ">";
}
}
@@ -489,6 +491,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
BluetoothA2dpSink.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
@@ -499,18 +502,18 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
};
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
}
private static void log(String msg) {
Log.d(TAG, msg);
Log.d(TAG, msg);
}
}

View File

@@ -25,6 +25,7 @@ import java.util.Arrays;
* Record of energy and activity information from controller and
* underlying bt stack state.Timestamp the record with system
* time
*
* @hide
*/
public final class BluetoothActivityEnergyInfo implements Parcelable {
@@ -42,7 +43,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
public static final int BT_STACK_STATE_STATE_IDLE = 3;
public BluetoothActivityEnergyInfo(long timestamp, int stackState,
long txTime, long rxTime, long idleTime, long energyUsed) {
long txTime, long rxTime, long idleTime, long energyUsed) {
mTimestamp = timestamp;
mBluetoothStackState = stackState;
mControllerTxTimeMs = txTime;
@@ -65,27 +66,29 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
@Override
public String toString() {
return "BluetoothActivityEnergyInfo{"
+ " mTimestamp=" + mTimestamp
+ " mBluetoothStackState=" + mBluetoothStackState
+ " mControllerTxTimeMs=" + mControllerTxTimeMs
+ " mControllerRxTimeMs=" + mControllerRxTimeMs
+ " mControllerIdleTimeMs=" + mControllerIdleTimeMs
+ " mControllerEnergyUsed=" + mControllerEnergyUsed
+ " mUidTraffic=" + Arrays.toString(mUidTraffic)
+ " }";
+ " mTimestamp=" + mTimestamp
+ " mBluetoothStackState=" + mBluetoothStackState
+ " mControllerTxTimeMs=" + mControllerTxTimeMs
+ " mControllerRxTimeMs=" + mControllerRxTimeMs
+ " mControllerIdleTimeMs=" + mControllerIdleTimeMs
+ " mControllerEnergyUsed=" + mControllerEnergyUsed
+ " mUidTraffic=" + Arrays.toString(mUidTraffic)
+ " }";
}
public static final Parcelable.Creator<BluetoothActivityEnergyInfo> CREATOR =
new Parcelable.Creator<BluetoothActivityEnergyInfo>() {
public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
return new BluetoothActivityEnergyInfo(in);
}
public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
return new BluetoothActivityEnergyInfo(in);
}
public BluetoothActivityEnergyInfo[] newArray(int size) {
return new BluetoothActivityEnergyInfo[size];
}
};
public BluetoothActivityEnergyInfo[] newArray(int size) {
return new BluetoothActivityEnergyInfo[size];
}
};
@Override
@SuppressWarnings("unchecked")
public void writeToParcel(Parcel out, int flags) {
out.writeLong(mTimestamp);
@@ -97,6 +100,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
out.writeTypedArray(mUidTraffic, flags);
}
@Override
public int describeContents() {
return 0;
}
@@ -131,6 +135,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
/**
* product of current(mA), voltage(V) and time(ms)
*
* @return energy used
*/
public long getControllerEnergyUsed() {
@@ -156,8 +161,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
* @return if the record is valid
*/
public boolean isValid() {
return ((mControllerTxTimeMs >=0) &&
(mControllerRxTimeMs >=0) &&
(mControllerIdleTimeMs >=0));
return ((mControllerTxTimeMs >= 0) && (mControllerRxTimeMs >= 0)
&& (mControllerIdleTimeMs >= 0));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -20,9 +20,9 @@ package android.bluetooth;
* Bluetooth Assigned Numbers.
* <p>
* For now we only include Company ID values.
* @see <a href="https://www.bluetooth.org/technical/assignednumbers/identifiers.htm">
* The Official Bluetooth SIG Member Website | Company Identifiers</a>
*
* @see <a href="https://www.bluetooth.org/technical/assignednumbers/identifiers.htm"> The Official
* Bluetooth SIG Member Website | Company Identifiers</a>
*/
public class BluetoothAssignedNumbers {

View File

@@ -41,10 +41,9 @@ public final class BluetoothAudioConfig implements Parcelable {
@Override
public boolean equals(Object o) {
if (o instanceof BluetoothAudioConfig) {
BluetoothAudioConfig bac = (BluetoothAudioConfig)o;
return (bac.mSampleRate == mSampleRate &&
bac.mChannelConfig == mChannelConfig &&
bac.mAudioFormat == mAudioFormat);
BluetoothAudioConfig bac = (BluetoothAudioConfig) o;
return (bac.mSampleRate == mSampleRate && bac.mChannelConfig == mChannelConfig
&& bac.mAudioFormat == mAudioFormat);
}
return false;
}
@@ -60,23 +59,26 @@ public final class BluetoothAudioConfig implements Parcelable {
+ ",mAudioFormat:" + mAudioFormat + "}";
}
@Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<BluetoothAudioConfig> CREATOR =
new Parcelable.Creator<BluetoothAudioConfig>() {
public BluetoothAudioConfig createFromParcel(Parcel in) {
int sampleRate = in.readInt();
int channelConfig = in.readInt();
int audioFormat = in.readInt();
return new BluetoothAudioConfig(sampleRate, channelConfig, audioFormat);
}
public BluetoothAudioConfig[] newArray(int size) {
return new BluetoothAudioConfig[size];
}
};
public BluetoothAudioConfig createFromParcel(Parcel in) {
int sampleRate = in.readInt();
int channelConfig = in.readInt();
int audioFormat = in.readInt();
return new BluetoothAudioConfig(sampleRate, channelConfig, audioFormat);
}
public BluetoothAudioConfig[] newArray(int size) {
return new BluetoothAudioConfig[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mSampleRate);
out.writeInt(mChannelConfig);
@@ -85,6 +87,7 @@ public final class BluetoothAudioConfig implements Parcelable {
/**
* Returns the sample rate in samples per second
*
* @return sample rate
*/
public int getSampleRate() {
@@ -94,6 +97,7 @@ public final class BluetoothAudioConfig implements Parcelable {
/**
* Returns the channel configuration (either {@link android.media.AudioFormat#CHANNEL_IN_MONO}
* or {@link android.media.AudioFormat#CHANNEL_IN_STEREO})
*
* @return channel configuration
*/
public int getChannelConfig() {
@@ -103,6 +107,7 @@ public final class BluetoothAudioConfig implements Parcelable {
/**
* Returns the channel audio format (either {@link android.media.AudioFormat#ENCODING_PCM_16BIT}
* or {@link android.media.AudioFormat#ENCODING_PCM_8BIT}
*
* @return audio format
*/
public int getAudioFormat() {

View File

@@ -26,68 +26,68 @@ public final class BluetoothAvrcp {
/*
* State flags for Passthrough commands
*/
public static final int PASSTHROUGH_STATE_PRESS = 0;
public static final int PASSTHROUGH_STATE_RELEASE = 1;
public static final int PASSTHROUGH_STATE_PRESS = 0;
public static final int PASSTHROUGH_STATE_RELEASE = 1;
/*
* Operation IDs for Passthrough commands
*/
public static final int PASSTHROUGH_ID_SELECT = 0x00; /* select */
public static final int PASSTHROUGH_ID_UP = 0x01; /* up */
public static final int PASSTHROUGH_ID_DOWN = 0x02; /* down */
public static final int PASSTHROUGH_ID_LEFT = 0x03; /* left */
public static final int PASSTHROUGH_ID_RIGHT = 0x04; /* right */
public static final int PASSTHROUGH_ID_RIGHT_UP = 0x05; /* right-up */
public static final int PASSTHROUGH_ID_RIGHT_DOWN = 0x06; /* right-down */
public static final int PASSTHROUGH_ID_LEFT_UP = 0x07; /* left-up */
public static final int PASSTHROUGH_ID_LEFT_DOWN = 0x08; /* left-down */
public static final int PASSTHROUGH_ID_ROOT_MENU = 0x09; /* root menu */
public static final int PASSTHROUGH_ID_SETUP_MENU = 0x0A; /* setup menu */
public static final int PASSTHROUGH_ID_CONT_MENU = 0x0B; /* contents menu */
public static final int PASSTHROUGH_ID_FAV_MENU = 0x0C; /* favorite menu */
public static final int PASSTHROUGH_ID_EXIT = 0x0D; /* exit */
public static final int PASSTHROUGH_ID_0 = 0x20; /* 0 */
public static final int PASSTHROUGH_ID_1 = 0x21; /* 1 */
public static final int PASSTHROUGH_ID_2 = 0x22; /* 2 */
public static final int PASSTHROUGH_ID_3 = 0x23; /* 3 */
public static final int PASSTHROUGH_ID_4 = 0x24; /* 4 */
public static final int PASSTHROUGH_ID_5 = 0x25; /* 5 */
public static final int PASSTHROUGH_ID_6 = 0x26; /* 6 */
public static final int PASSTHROUGH_ID_7 = 0x27; /* 7 */
public static final int PASSTHROUGH_ID_8 = 0x28; /* 8 */
public static final int PASSTHROUGH_ID_9 = 0x29; /* 9 */
public static final int PASSTHROUGH_ID_DOT = 0x2A; /* dot */
public static final int PASSTHROUGH_ID_ENTER = 0x2B; /* enter */
public static final int PASSTHROUGH_ID_CLEAR = 0x2C; /* clear */
public static final int PASSTHROUGH_ID_CHAN_UP = 0x30; /* channel up */
public static final int PASSTHROUGH_ID_CHAN_DOWN = 0x31; /* channel down */
public static final int PASSTHROUGH_ID_PREV_CHAN = 0x32; /* previous channel */
public static final int PASSTHROUGH_ID_SOUND_SEL = 0x33; /* sound select */
public static final int PASSTHROUGH_ID_INPUT_SEL = 0x34; /* input select */
public static final int PASSTHROUGH_ID_DISP_INFO = 0x35; /* display information */
public static final int PASSTHROUGH_ID_HELP = 0x36; /* help */
public static final int PASSTHROUGH_ID_PAGE_UP = 0x37; /* page up */
public static final int PASSTHROUGH_ID_PAGE_DOWN = 0x38; /* page down */
public static final int PASSTHROUGH_ID_POWER = 0x40; /* power */
public static final int PASSTHROUGH_ID_VOL_UP = 0x41; /* volume up */
public static final int PASSTHROUGH_ID_VOL_DOWN = 0x42; /* volume down */
public static final int PASSTHROUGH_ID_MUTE = 0x43; /* mute */
public static final int PASSTHROUGH_ID_PLAY = 0x44; /* play */
public static final int PASSTHROUGH_ID_STOP = 0x45; /* stop */
public static final int PASSTHROUGH_ID_PAUSE = 0x46; /* pause */
public static final int PASSTHROUGH_ID_RECORD = 0x47; /* record */
public static final int PASSTHROUGH_ID_REWIND = 0x48; /* rewind */
public static final int PASSTHROUGH_ID_FAST_FOR = 0x49; /* fast forward */
public static final int PASSTHROUGH_ID_EJECT = 0x4A; /* eject */
public static final int PASSTHROUGH_ID_FORWARD = 0x4B; /* forward */
public static final int PASSTHROUGH_ID_BACKWARD = 0x4C; /* backward */
public static final int PASSTHROUGH_ID_ANGLE = 0x50; /* angle */
public static final int PASSTHROUGH_ID_SUBPICT = 0x51; /* subpicture */
public static final int PASSTHROUGH_ID_F1 = 0x71; /* F1 */
public static final int PASSTHROUGH_ID_F2 = 0x72; /* F2 */
public static final int PASSTHROUGH_ID_F3 = 0x73; /* F3 */
public static final int PASSTHROUGH_ID_F4 = 0x74; /* F4 */
public static final int PASSTHROUGH_ID_F5 = 0x75; /* F5 */
public static final int PASSTHROUGH_ID_VENDOR = 0x7E; /* vendor unique */
public static final int PASSTHROUGH_ID_SELECT = 0x00; /* select */
public static final int PASSTHROUGH_ID_UP = 0x01; /* up */
public static final int PASSTHROUGH_ID_DOWN = 0x02; /* down */
public static final int PASSTHROUGH_ID_LEFT = 0x03; /* left */
public static final int PASSTHROUGH_ID_RIGHT = 0x04; /* right */
public static final int PASSTHROUGH_ID_RIGHT_UP = 0x05; /* right-up */
public static final int PASSTHROUGH_ID_RIGHT_DOWN = 0x06; /* right-down */
public static final int PASSTHROUGH_ID_LEFT_UP = 0x07; /* left-up */
public static final int PASSTHROUGH_ID_LEFT_DOWN = 0x08; /* left-down */
public static final int PASSTHROUGH_ID_ROOT_MENU = 0x09; /* root menu */
public static final int PASSTHROUGH_ID_SETUP_MENU = 0x0A; /* setup menu */
public static final int PASSTHROUGH_ID_CONT_MENU = 0x0B; /* contents menu */
public static final int PASSTHROUGH_ID_FAV_MENU = 0x0C; /* favorite menu */
public static final int PASSTHROUGH_ID_EXIT = 0x0D; /* exit */
public static final int PASSTHROUGH_ID_0 = 0x20; /* 0 */
public static final int PASSTHROUGH_ID_1 = 0x21; /* 1 */
public static final int PASSTHROUGH_ID_2 = 0x22; /* 2 */
public static final int PASSTHROUGH_ID_3 = 0x23; /* 3 */
public static final int PASSTHROUGH_ID_4 = 0x24; /* 4 */
public static final int PASSTHROUGH_ID_5 = 0x25; /* 5 */
public static final int PASSTHROUGH_ID_6 = 0x26; /* 6 */
public static final int PASSTHROUGH_ID_7 = 0x27; /* 7 */
public static final int PASSTHROUGH_ID_8 = 0x28; /* 8 */
public static final int PASSTHROUGH_ID_9 = 0x29; /* 9 */
public static final int PASSTHROUGH_ID_DOT = 0x2A; /* dot */
public static final int PASSTHROUGH_ID_ENTER = 0x2B; /* enter */
public static final int PASSTHROUGH_ID_CLEAR = 0x2C; /* clear */
public static final int PASSTHROUGH_ID_CHAN_UP = 0x30; /* channel up */
public static final int PASSTHROUGH_ID_CHAN_DOWN = 0x31; /* channel down */
public static final int PASSTHROUGH_ID_PREV_CHAN = 0x32; /* previous channel */
public static final int PASSTHROUGH_ID_SOUND_SEL = 0x33; /* sound select */
public static final int PASSTHROUGH_ID_INPUT_SEL = 0x34; /* input select */
public static final int PASSTHROUGH_ID_DISP_INFO = 0x35; /* display information */
public static final int PASSTHROUGH_ID_HELP = 0x36; /* help */
public static final int PASSTHROUGH_ID_PAGE_UP = 0x37; /* page up */
public static final int PASSTHROUGH_ID_PAGE_DOWN = 0x38; /* page down */
public static final int PASSTHROUGH_ID_POWER = 0x40; /* power */
public static final int PASSTHROUGH_ID_VOL_UP = 0x41; /* volume up */
public static final int PASSTHROUGH_ID_VOL_DOWN = 0x42; /* volume down */
public static final int PASSTHROUGH_ID_MUTE = 0x43; /* mute */
public static final int PASSTHROUGH_ID_PLAY = 0x44; /* play */
public static final int PASSTHROUGH_ID_STOP = 0x45; /* stop */
public static final int PASSTHROUGH_ID_PAUSE = 0x46; /* pause */
public static final int PASSTHROUGH_ID_RECORD = 0x47; /* record */
public static final int PASSTHROUGH_ID_REWIND = 0x48; /* rewind */
public static final int PASSTHROUGH_ID_FAST_FOR = 0x49; /* fast forward */
public static final int PASSTHROUGH_ID_EJECT = 0x4A; /* eject */
public static final int PASSTHROUGH_ID_FORWARD = 0x4B; /* forward */
public static final int PASSTHROUGH_ID_BACKWARD = 0x4C; /* backward */
public static final int PASSTHROUGH_ID_ANGLE = 0x50; /* angle */
public static final int PASSTHROUGH_ID_SUBPICT = 0x51; /* subpicture */
public static final int PASSTHROUGH_ID_F1 = 0x71; /* F1 */
public static final int PASSTHROUGH_ID_F2 = 0x72; /* F2 */
public static final int PASSTHROUGH_ID_F3 = 0x73; /* F3 */
public static final int PASSTHROUGH_ID_F4 = 0x74; /* F4 */
public static final int PASSTHROUGH_ID_F5 = 0x75; /* F5 */
public static final int PASSTHROUGH_ID_VENDOR = 0x7E; /* vendor unique */
public static final int PASSTHROUGH_KEYPRESSED_RELEASE = 0x80;
}

View File

@@ -20,8 +20,6 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.media.MediaMetadata;
import android.media.session.PlaybackState;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -34,7 +32,7 @@ import java.util.List;
* This class provides the public APIs to control the Bluetooth AVRCP Controller. It currently
* supports player information, playback support and track metadata.
*
*<p>BluetoothAvrcpController is a proxy object for controlling the Bluetooth AVRCP
* <p>BluetoothAvrcpController is a proxy object for controlling the Bluetooth AVRCP
* Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
* the BluetoothAvrcpController proxy object.
*
@@ -51,9 +49,9 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -64,19 +62,19 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
* receive.
*/
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED";
/**
* Intent used to broadcast the change in player application setting state on AVRCP AG.
*
* <p>This intent will have the following extras:
* <ul>
* <li> {@link #EXTRA_PLAYER_SETTING} - {@link BluetoothAvrcpPlayerSettings} containing the
* most recent player setting. </li>
* <li> {@link #EXTRA_PLAYER_SETTING} - {@link BluetoothAvrcpPlayerSettings} containing the
* most recent player setting. </li>
* </ul>
*/
public static final String ACTION_PLAYER_SETTING =
"android.bluetooth.avrcp-controller.profile.action.PLAYER_SETTING";
"android.bluetooth.avrcp-controller.profile.action.PLAYER_SETTING";
public static final String EXTRA_PLAYER_SETTING =
"android.bluetooth.avrcp-controller.profile.extra.PLAYER_SETTING";
@@ -86,39 +84,38 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
private IBluetoothAvrcpController mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
doBind();
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG, "", re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG, "", re);
}
} catch (Exception re) {
Log.e(TAG,"",re);
}
}
}
}
};
};
/**
* Create a BluetoothAvrcpController proxy object for interacting with the local
* Bluetooth AVRCP service.
*
*/
/*package*/ BluetoothAvrcpController(Context context, ServiceListener l) {
mContext = context;
@@ -129,7 +126,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -155,7 +152,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -165,12 +162,13 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
@Override
public void finalize() {
close();
}
@@ -178,6 +176,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
if (mService != null && isEnabled()) {
@@ -195,6 +194,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
if (mService != null && isEnabled()) {
@@ -212,10 +212,11 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
if (mService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
try {
return mService.getConnectionState(device);
} catch (RemoteException e) {
@@ -264,12 +265,13 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
return false;
}
/*
/**
* Send Group Navigation Command to Remote.
* possible keycode values: next_grp, previous_grp defined above
*/
public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = " + keyState);
Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
+ keyState);
if (mService != null && isEnabled()) {
try {
mService.sendGroupNavigationCmd(device, keyCode, keyState);
@@ -292,6 +294,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
BluetoothAvrcpController.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
@@ -302,18 +305,18 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
};
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
}
private static void log(String msg) {
Log.d(TAG, msg);
Log.d(TAG, msg);
}
}

View File

@@ -34,22 +34,22 @@ public final class BluetoothAvrcpPlayerSettings implements Parcelable {
/**
* Equalizer setting.
*/
public static final int SETTING_EQUALIZER = 0x01;
public static final int SETTING_EQUALIZER = 0x01;
/**
* Repeat setting.
*/
public static final int SETTING_REPEAT = 0x02;
public static final int SETTING_REPEAT = 0x02;
/**
* Shuffle setting.
*/
public static final int SETTING_SHUFFLE = 0x04;
public static final int SETTING_SHUFFLE = 0x04;
/**
* Scan mode setting.
*/
public static final int SETTING_SCAN = 0x08;
public static final int SETTING_SCAN = 0x08;
/**
* Invalid state.
@@ -82,16 +82,16 @@ public final class BluetoothAvrcpPlayerSettings implements Parcelable {
/**
* All track repeat/shuffle.
*
* Applies to {@link SETTING_REPEAT}, {@link SETTING_SHUFFLE} and {@link SETTING_SCAN}.
* Applies to {@link #SETTING_REPEAT}, {@link #SETTING_SHUFFLE} and {@link #SETTING_SCAN}.
*/
public static final int STATE_ALL_TRACK = 0x03;
public static final int STATE_ALL_TRACK = 0x03;
/**
* Group repeat/shuffle.
*
* Applies to {@link SETTING_REPEAT}, {@link SETTING_SHUFFLE} and {@link SETTING_SCAN}.
* Applies to {@link #SETTING_REPEAT}, {@link #SETTING_SHUFFLE} and {@link #SETTING_SCAN}.
*/
public static final int STATE_GROUP = 0x04;
public static final int STATE_GROUP = 0x04;
/**
* List of supported settings ORed.
@@ -103,10 +103,12 @@ public final class BluetoothAvrcpPlayerSettings implements Parcelable {
*/
private Map<Integer, Integer> mSettingsValue = new HashMap<Integer, Integer>();
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mSettings);
out.writeInt(mSettingsValue.size());
@@ -116,8 +118,8 @@ public final class BluetoothAvrcpPlayerSettings implements Parcelable {
}
}
public static final Parcelable.Creator<BluetoothAvrcpPlayerSettings> CREATOR
= new Parcelable.Creator<BluetoothAvrcpPlayerSettings>() {
public static final Parcelable.Creator<BluetoothAvrcpPlayerSettings> CREATOR =
new Parcelable.Creator<BluetoothAvrcpPlayerSettings>() {
public BluetoothAvrcpPlayerSettings createFromParcel(Parcel in) {
return new BluetoothAvrcpPlayerSettings(in);
}
@@ -157,6 +159,7 @@ public final class BluetoothAvrcpPlayerSettings implements Parcelable {
* Add a setting value.
*
* The setting must be part of possible settings in {@link getSettings()}.
*
* @param setting setting config.
* @param value value for the setting.
* @throws IllegalStateException if the setting is not supported.
@@ -173,6 +176,7 @@ public final class BluetoothAvrcpPlayerSettings implements Parcelable {
* Get a setting value.
*
* The setting must be part of possible settings in {@link getSettings()}.
*
* @param setting setting config.
* @return value value for the setting.
* @throws IllegalStateException if the setting is not supported.

View File

@@ -51,6 +51,7 @@ import android.os.Parcelable;
public final class BluetoothClass implements Parcelable {
/**
* Legacy error value. Applications should use null instead.
*
* @hide
*/
public static final int ERROR = 0xFF000000;
@@ -65,7 +66,7 @@ public final class BluetoothClass implements Parcelable {
@Override
public boolean equals(Object o) {
if (o instanceof BluetoothClass) {
return mClass == ((BluetoothClass)o).mClass;
return mClass == ((BluetoothClass) o).mClass;
}
return false;
}
@@ -80,20 +81,23 @@ public final class BluetoothClass implements Parcelable {
return Integer.toHexString(mClass);
}
@Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<BluetoothClass> CREATOR =
new Parcelable.Creator<BluetoothClass>() {
public BluetoothClass createFromParcel(Parcel in) {
return new BluetoothClass(in.readInt());
}
public BluetoothClass[] newArray(int size) {
return new BluetoothClass[size];
}
};
public BluetoothClass createFromParcel(Parcel in) {
return new BluetoothClass(in.readInt());
}
public BluetoothClass[] newArray(int size) {
return new BluetoothClass[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mClass);
}
@@ -103,17 +107,17 @@ public final class BluetoothClass implements Parcelable {
* <p>Each {@link BluetoothClass} encodes zero or more service classes.
*/
public static final class Service {
private static final int BITMASK = 0xFFE000;
private static final int BITMASK = 0xFFE000;
public static final int LIMITED_DISCOVERABILITY = 0x002000;
public static final int POSITIONING = 0x010000;
public static final int NETWORKING = 0x020000;
public static final int RENDER = 0x040000;
public static final int CAPTURE = 0x080000;
public static final int OBJECT_TRANSFER = 0x100000;
public static final int AUDIO = 0x200000;
public static final int TELEPHONY = 0x400000;
public static final int INFORMATION = 0x800000;
public static final int POSITIONING = 0x010000;
public static final int NETWORKING = 0x020000;
public static final int RENDER = 0x040000;
public static final int CAPTURE = 0x080000;
public static final int OBJECT_TRANSFER = 0x100000;
public static final int AUDIO = 0x200000;
public static final int TELEPHONY = 0x400000;
public static final int INFORMATION = 0x800000;
}
/**
@@ -141,91 +145,91 @@ public final class BluetoothClass implements Parcelable {
* <p>See {@link BluetoothClass.Service} for service class constants.
*/
public static class Device {
private static final int BITMASK = 0x1FFC;
private static final int BITMASK = 0x1FFC;
/**
* Defines all major device class constants.
* <p>See {@link BluetoothClass.Device} for minor classes.
*/
public static class Major {
private static final int BITMASK = 0x1F00;
private static final int BITMASK = 0x1F00;
public static final int MISC = 0x0000;
public static final int COMPUTER = 0x0100;
public static final int PHONE = 0x0200;
public static final int NETWORKING = 0x0300;
public static final int AUDIO_VIDEO = 0x0400;
public static final int PERIPHERAL = 0x0500;
public static final int IMAGING = 0x0600;
public static final int WEARABLE = 0x0700;
public static final int TOY = 0x0800;
public static final int HEALTH = 0x0900;
public static final int UNCATEGORIZED = 0x1F00;
public static final int MISC = 0x0000;
public static final int COMPUTER = 0x0100;
public static final int PHONE = 0x0200;
public static final int NETWORKING = 0x0300;
public static final int AUDIO_VIDEO = 0x0400;
public static final int PERIPHERAL = 0x0500;
public static final int IMAGING = 0x0600;
public static final int WEARABLE = 0x0700;
public static final int TOY = 0x0800;
public static final int HEALTH = 0x0900;
public static final int UNCATEGORIZED = 0x1F00;
}
// Devices in the COMPUTER major class
public static final int COMPUTER_UNCATEGORIZED = 0x0100;
public static final int COMPUTER_DESKTOP = 0x0104;
public static final int COMPUTER_SERVER = 0x0108;
public static final int COMPUTER_LAPTOP = 0x010C;
public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110;
public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114;
public static final int COMPUTER_WEARABLE = 0x0118;
public static final int COMPUTER_UNCATEGORIZED = 0x0100;
public static final int COMPUTER_DESKTOP = 0x0104;
public static final int COMPUTER_SERVER = 0x0108;
public static final int COMPUTER_LAPTOP = 0x010C;
public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110;
public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114;
public static final int COMPUTER_WEARABLE = 0x0118;
// Devices in the PHONE major class
public static final int PHONE_UNCATEGORIZED = 0x0200;
public static final int PHONE_CELLULAR = 0x0204;
public static final int PHONE_CORDLESS = 0x0208;
public static final int PHONE_SMART = 0x020C;
public static final int PHONE_MODEM_OR_GATEWAY = 0x0210;
public static final int PHONE_ISDN = 0x0214;
public static final int PHONE_UNCATEGORIZED = 0x0200;
public static final int PHONE_CELLULAR = 0x0204;
public static final int PHONE_CORDLESS = 0x0208;
public static final int PHONE_SMART = 0x020C;
public static final int PHONE_MODEM_OR_GATEWAY = 0x0210;
public static final int PHONE_ISDN = 0x0214;
// Minor classes for the AUDIO_VIDEO major class
public static final int AUDIO_VIDEO_UNCATEGORIZED = 0x0400;
public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404;
public static final int AUDIO_VIDEO_HANDSFREE = 0x0408;
public static final int AUDIO_VIDEO_UNCATEGORIZED = 0x0400;
public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404;
public static final int AUDIO_VIDEO_HANDSFREE = 0x0408;
//public static final int AUDIO_VIDEO_RESERVED = 0x040C;
public static final int AUDIO_VIDEO_MICROPHONE = 0x0410;
public static final int AUDIO_VIDEO_LOUDSPEAKER = 0x0414;
public static final int AUDIO_VIDEO_HEADPHONES = 0x0418;
public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C;
public static final int AUDIO_VIDEO_CAR_AUDIO = 0x0420;
public static final int AUDIO_VIDEO_SET_TOP_BOX = 0x0424;
public static final int AUDIO_VIDEO_HIFI_AUDIO = 0x0428;
public static final int AUDIO_VIDEO_VCR = 0x042C;
public static final int AUDIO_VIDEO_VIDEO_CAMERA = 0x0430;
public static final int AUDIO_VIDEO_CAMCORDER = 0x0434;
public static final int AUDIO_VIDEO_VIDEO_MONITOR = 0x0438;
public static final int AUDIO_VIDEO_MICROPHONE = 0x0410;
public static final int AUDIO_VIDEO_LOUDSPEAKER = 0x0414;
public static final int AUDIO_VIDEO_HEADPHONES = 0x0418;
public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C;
public static final int AUDIO_VIDEO_CAR_AUDIO = 0x0420;
public static final int AUDIO_VIDEO_SET_TOP_BOX = 0x0424;
public static final int AUDIO_VIDEO_HIFI_AUDIO = 0x0428;
public static final int AUDIO_VIDEO_VCR = 0x042C;
public static final int AUDIO_VIDEO_VIDEO_CAMERA = 0x0430;
public static final int AUDIO_VIDEO_CAMCORDER = 0x0434;
public static final int AUDIO_VIDEO_VIDEO_MONITOR = 0x0438;
public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C;
public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440;
public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440;
//public static final int AUDIO_VIDEO_RESERVED = 0x0444;
public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448;
public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448;
// Devices in the WEARABLE major class
public static final int WEARABLE_UNCATEGORIZED = 0x0700;
public static final int WEARABLE_WRIST_WATCH = 0x0704;
public static final int WEARABLE_PAGER = 0x0708;
public static final int WEARABLE_JACKET = 0x070C;
public static final int WEARABLE_HELMET = 0x0710;
public static final int WEARABLE_GLASSES = 0x0714;
public static final int WEARABLE_UNCATEGORIZED = 0x0700;
public static final int WEARABLE_WRIST_WATCH = 0x0704;
public static final int WEARABLE_PAGER = 0x0708;
public static final int WEARABLE_JACKET = 0x070C;
public static final int WEARABLE_HELMET = 0x0710;
public static final int WEARABLE_GLASSES = 0x0714;
// Devices in the TOY major class
public static final int TOY_UNCATEGORIZED = 0x0800;
public static final int TOY_ROBOT = 0x0804;
public static final int TOY_VEHICLE = 0x0808;
public static final int TOY_DOLL_ACTION_FIGURE = 0x080C;
public static final int TOY_CONTROLLER = 0x0810;
public static final int TOY_GAME = 0x0814;
public static final int TOY_UNCATEGORIZED = 0x0800;
public static final int TOY_ROBOT = 0x0804;
public static final int TOY_VEHICLE = 0x0808;
public static final int TOY_DOLL_ACTION_FIGURE = 0x080C;
public static final int TOY_CONTROLLER = 0x0810;
public static final int TOY_GAME = 0x0814;
// Devices in the HEALTH major class
public static final int HEALTH_UNCATEGORIZED = 0x0900;
public static final int HEALTH_BLOOD_PRESSURE = 0x0904;
public static final int HEALTH_THERMOMETER = 0x0908;
public static final int HEALTH_WEIGHING = 0x090C;
public static final int HEALTH_GLUCOSE = 0x0910;
public static final int HEALTH_PULSE_OXIMETER = 0x0914;
public static final int HEALTH_PULSE_RATE = 0x0918;
public static final int HEALTH_DATA_DISPLAY = 0x091C;
public static final int HEALTH_UNCATEGORIZED = 0x0900;
public static final int HEALTH_BLOOD_PRESSURE = 0x0904;
public static final int HEALTH_THERMOMETER = 0x0908;
public static final int HEALTH_WEIGHING = 0x090C;
public static final int HEALTH_GLUCOSE = 0x0910;
public static final int HEALTH_PULSE_OXIMETER = 0x0914;
public static final int HEALTH_PULSE_RATE = 0x0918;
public static final int HEALTH_DATA_DISPLAY = 0x091C;
// Devices in PERIPHERAL major class
/**
@@ -235,15 +239,15 @@ public final class BluetoothClass implements Parcelable {
/**
* @hide
*/
public static final int PERIPHERAL_KEYBOARD = 0x0540;
public static final int PERIPHERAL_KEYBOARD = 0x0540;
/**
* @hide
*/
public static final int PERIPHERAL_POINTING = 0x0580;
public static final int PERIPHERAL_POINTING = 0x0580;
/**
* @hide
*/
public static final int PERIPHERAL_KEYBOARD_POINTING = 0x05C0;
public static final int PERIPHERAL_KEYBOARD_POINTING = 0x05C0;
}
/**
@@ -291,6 +295,7 @@ public final class BluetoothClass implements Parcelable {
* This is a simple heuristic that tries to guess if a device with the
* given class bits might support specified profile. It is not accurate for all
* devices. It tries to err on the side of false positives.
*
* @param profile The profile to be checked
* @return True if this device might support specified profile.
* @hide
@@ -322,7 +327,7 @@ public final class BluetoothClass implements Parcelable {
switch (getDeviceClass()) {
case Device.AUDIO_VIDEO_HIFI_AUDIO:
case Device.AUDIO_VIDEO_SET_TOP_BOX:
case Device.AUDIO_VIDEO_VCR :
case Device.AUDIO_VIDEO_VCR:
return true;
default:
return false;
@@ -367,7 +372,7 @@ public final class BluetoothClass implements Parcelable {
}
} else if (profile == PROFILE_HID) {
return (getDeviceClass() & Device.Major.PERIPHERAL) == Device.Major.PERIPHERAL;
} else if (profile == PROFILE_PANU || profile == PROFILE_NAP){
} else if (profile == PROFILE_PANU || profile == PROFILE_NAP) {
// No good way to distinguish between the two, based on class bits.
if (hasService(Service.NETWORKING)) {
return true;

View File

@@ -32,12 +32,12 @@ public final class BluetoothCodecConfig implements Parcelable {
// Add an entry for each source codec here.
// NOTE: The values should be same as those listed in the following file:
// hardware/libhardware/include/hardware/bt_av.h
public static final int SOURCE_CODEC_TYPE_SBC = 0;
public static final int SOURCE_CODEC_TYPE_AAC = 1;
public static final int SOURCE_CODEC_TYPE_APTX = 2;
public static final int SOURCE_CODEC_TYPE_SBC = 0;
public static final int SOURCE_CODEC_TYPE_AAC = 1;
public static final int SOURCE_CODEC_TYPE_APTX = 2;
public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
public static final int SOURCE_CODEC_TYPE_LDAC = 4;
public static final int SOURCE_CODEC_TYPE_MAX = 5;
public static final int SOURCE_CODEC_TYPE_LDAC = 4;
public static final int SOURCE_CODEC_TYPE_MAX = 5;
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
@@ -45,21 +45,21 @@ public final class BluetoothCodecConfig implements Parcelable {
public static final int CODEC_PRIORITY_DEFAULT = 0;
public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
public static final int SAMPLE_RATE_NONE = 0;
public static final int SAMPLE_RATE_44100 = 0x1 << 0;
public static final int SAMPLE_RATE_48000 = 0x1 << 1;
public static final int SAMPLE_RATE_88200 = 0x1 << 2;
public static final int SAMPLE_RATE_96000 = 0x1 << 3;
public static final int SAMPLE_RATE_NONE = 0;
public static final int SAMPLE_RATE_44100 = 0x1 << 0;
public static final int SAMPLE_RATE_48000 = 0x1 << 1;
public static final int SAMPLE_RATE_88200 = 0x1 << 2;
public static final int SAMPLE_RATE_96000 = 0x1 << 3;
public static final int SAMPLE_RATE_176400 = 0x1 << 4;
public static final int SAMPLE_RATE_192000 = 0x1 << 5;
public static final int BITS_PER_SAMPLE_NONE = 0;
public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
public static final int CHANNEL_MODE_NONE = 0;
public static final int CHANNEL_MODE_MONO = 0x1 << 0;
public static final int CHANNEL_MODE_NONE = 0;
public static final int CHANNEL_MODE_MONO = 0x1 << 0;
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
private final int mCodecType;
@@ -73,10 +73,10 @@ public final class BluetoothCodecConfig implements Parcelable {
private final long mCodecSpecific4;
public BluetoothCodecConfig(int codecType, int codecPriority,
int sampleRate, int bitsPerSample,
int channelMode, long codecSpecific1,
long codecSpecific2, long codecSpecific3,
long codecSpecific4) {
int sampleRate, int bitsPerSample,
int channelMode, long codecSpecific1,
long codecSpecific2, long codecSpecific3,
long codecSpecific4) {
mCodecType = codecType;
mCodecPriority = codecPriority;
mSampleRate = sampleRate;
@@ -91,16 +91,16 @@ public final class BluetoothCodecConfig implements Parcelable {
@Override
public boolean equals(Object o) {
if (o instanceof BluetoothCodecConfig) {
BluetoothCodecConfig other = (BluetoothCodecConfig)o;
return (other.mCodecType == mCodecType &&
other.mCodecPriority == mCodecPriority &&
other.mSampleRate == mSampleRate &&
other.mBitsPerSample == mBitsPerSample &&
other.mChannelMode == mChannelMode &&
other.mCodecSpecific1 == mCodecSpecific1 &&
other.mCodecSpecific2 == mCodecSpecific2 &&
other.mCodecSpecific3 == mCodecSpecific3 &&
other.mCodecSpecific4 == mCodecSpecific4);
BluetoothCodecConfig other = (BluetoothCodecConfig) o;
return (other.mCodecType == mCodecType
&& other.mCodecPriority == mCodecPriority
&& other.mSampleRate == mSampleRate
&& other.mBitsPerSample == mBitsPerSample
&& other.mChannelMode == mChannelMode
&& other.mCodecSpecific1 == mCodecSpecific1
&& other.mCodecSpecific2 == mCodecSpecific2
&& other.mCodecSpecific3 == mCodecSpecific3
&& other.mCodecSpecific4 == mCodecSpecific4);
}
return false;
}
@@ -108,32 +108,30 @@ public final class BluetoothCodecConfig implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
mBitsPerSample, mChannelMode, mCodecSpecific1,
mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
mBitsPerSample, mChannelMode, mCodecSpecific1,
mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
}
/**
* Checks whether the object contains valid codec configuration.
*
* @return true if the object contains valid codec configuration,
* otherwise false.
* @return true if the object contains valid codec configuration, otherwise false.
*/
public boolean isValid() {
return (mSampleRate != SAMPLE_RATE_NONE) &&
(mBitsPerSample != BITS_PER_SAMPLE_NONE) &&
(mChannelMode != CHANNEL_MODE_NONE);
return (mSampleRate != SAMPLE_RATE_NONE)
&& (mBitsPerSample != BITS_PER_SAMPLE_NONE)
&& (mChannelMode != CHANNEL_MODE_NONE);
}
/**
* Adds capability string to an existing string.
*
* @param prevStr the previous string with the capabilities. Can be
* a null pointer.
* @param prevStr the previous string with the capabilities. Can be a null pointer.
* @param capStr the capability string to append to prevStr argument.
* @return the result string in the form "prevStr|capStr".
*/
private static String appendCapabilityToString(String prevStr,
String capStr) {
String capStr) {
if (prevStr == null) {
return capStr;
}
@@ -190,48 +188,51 @@ public final class BluetoothCodecConfig implements Parcelable {
channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
}
return "{codecName:" + getCodecName() +
",mCodecType:" + mCodecType +
",mCodecPriority:" + mCodecPriority +
",mSampleRate:" + String.format("0x%x", mSampleRate) +
"(" + sampleRateStr + ")" +
",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) +
"(" + bitsPerSampleStr + ")" +
",mChannelMode:" + String.format("0x%x", mChannelMode) +
"(" + channelModeStr + ")" +
",mCodecSpecific1:" + mCodecSpecific1 +
",mCodecSpecific2:" + mCodecSpecific2 +
",mCodecSpecific3:" + mCodecSpecific3 +
",mCodecSpecific4:" + mCodecSpecific4 + "}";
return "{codecName:" + getCodecName()
+ ",mCodecType:" + mCodecType
+ ",mCodecPriority:" + mCodecPriority
+ ",mSampleRate:" + String.format("0x%x", mSampleRate)
+ "(" + sampleRateStr + ")"
+ ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample)
+ "(" + bitsPerSampleStr + ")"
+ ",mChannelMode:" + String.format("0x%x", mChannelMode)
+ "(" + channelModeStr + ")"
+ ",mCodecSpecific1:" + mCodecSpecific1
+ ",mCodecSpecific2:" + mCodecSpecific2
+ ",mCodecSpecific3:" + mCodecSpecific3
+ ",mCodecSpecific4:" + mCodecSpecific4 + "}";
}
@Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<BluetoothCodecConfig> CREATOR =
new Parcelable.Creator<BluetoothCodecConfig>() {
public BluetoothCodecConfig createFromParcel(Parcel in) {
final int codecType = in.readInt();
final int codecPriority = in.readInt();
final int sampleRate = in.readInt();
final int bitsPerSample = in.readInt();
final int channelMode = in.readInt();
final long codecSpecific1 = in.readLong();
final long codecSpecific2 = in.readLong();
final long codecSpecific3 = in.readLong();
final long codecSpecific4 = in.readLong();
return new BluetoothCodecConfig(codecType, codecPriority,
sampleRate, bitsPerSample,
channelMode, codecSpecific1,
codecSpecific2, codecSpecific3,
codecSpecific4);
}
public BluetoothCodecConfig[] newArray(int size) {
return new BluetoothCodecConfig[size];
}
};
public BluetoothCodecConfig createFromParcel(Parcel in) {
final int codecType = in.readInt();
final int codecPriority = in.readInt();
final int sampleRate = in.readInt();
final int bitsPerSample = in.readInt();
final int channelMode = in.readInt();
final long codecSpecific1 = in.readLong();
final long codecSpecific2 = in.readLong();
final long codecSpecific3 = in.readLong();
final long codecSpecific4 = in.readLong();
return new BluetoothCodecConfig(codecType, codecPriority,
sampleRate, bitsPerSample,
channelMode, codecSpecific1,
codecSpecific2, codecSpecific3,
codecSpecific4);
}
public BluetoothCodecConfig[] newArray(int size) {
return new BluetoothCodecConfig[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mCodecType);
out.writeInt(mCodecPriority);
@@ -251,20 +252,20 @@ public final class BluetoothCodecConfig implements Parcelable {
*/
public String getCodecName() {
switch (mCodecType) {
case SOURCE_CODEC_TYPE_SBC:
return "SBC";
case SOURCE_CODEC_TYPE_AAC:
return "AAC";
case SOURCE_CODEC_TYPE_APTX:
return "aptX";
case SOURCE_CODEC_TYPE_APTX_HD:
return "aptX HD";
case SOURCE_CODEC_TYPE_LDAC:
return "LDAC";
case SOURCE_CODEC_TYPE_INVALID:
return "INVALID CODEC";
default:
break;
case SOURCE_CODEC_TYPE_SBC:
return "SBC";
case SOURCE_CODEC_TYPE_AAC:
return "AAC";
case SOURCE_CODEC_TYPE_APTX:
return "aptX";
case SOURCE_CODEC_TYPE_APTX_HD:
return "aptX HD";
case SOURCE_CODEC_TYPE_LDAC:
return "LDAC";
case SOURCE_CODEC_TYPE_INVALID:
return "INVALID CODEC";
default:
break;
}
return "UNKNOWN CODEC(" + mCodecType + ")";
}
@@ -397,8 +398,8 @@ public final class BluetoothCodecConfig implements Parcelable {
* @return true if the audio feeding parameters are same, otherwise false
*/
public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) {
return (other != null && other.mSampleRate == mSampleRate &&
other.mBitsPerSample == mBitsPerSample &&
other.mChannelMode == mChannelMode);
return (other != null && other.mSampleRate == mSampleRate
&& other.mBitsPerSample == mBitsPerSample
&& other.mChannelMode == mChannelMode);
}
}

View File

@@ -38,15 +38,15 @@ public final class BluetoothCodecStatus implements Parcelable {
* profile.
*/
public static final String EXTRA_CODEC_STATUS =
"android.bluetooth.codec.extra.CODEC_STATUS";
"android.bluetooth.codec.extra.CODEC_STATUS";
private final BluetoothCodecConfig mCodecConfig;
private final BluetoothCodecConfig[] mCodecsLocalCapabilities;
private final BluetoothCodecConfig[] mCodecsSelectableCapabilities;
public BluetoothCodecStatus(BluetoothCodecConfig codecConfig,
BluetoothCodecConfig[] codecsLocalCapabilities,
BluetoothCodecConfig[] codecsSelectableCapabilities) {
BluetoothCodecConfig[] codecsLocalCapabilities,
BluetoothCodecConfig[] codecsSelectableCapabilities) {
mCodecConfig = codecConfig;
mCodecsLocalCapabilities = codecsLocalCapabilities;
mCodecsSelectableCapabilities = codecsSelectableCapabilities;
@@ -55,12 +55,11 @@ public final class BluetoothCodecStatus implements Parcelable {
@Override
public boolean equals(Object o) {
if (o instanceof BluetoothCodecStatus) {
BluetoothCodecStatus other = (BluetoothCodecStatus)o;
return (Objects.equals(other.mCodecConfig, mCodecConfig) &&
Objects.equals(other.mCodecsLocalCapabilities,
mCodecsLocalCapabilities) &&
Objects.equals(other.mCodecsSelectableCapabilities,
mCodecsSelectableCapabilities));
BluetoothCodecStatus other = (BluetoothCodecStatus) o;
return (Objects.equals(other.mCodecConfig, mCodecConfig)
&& Objects.equals(other.mCodecsLocalCapabilities, mCodecsLocalCapabilities)
&& Objects.equals(other.mCodecsSelectableCapabilities,
mCodecsSelectableCapabilities));
}
return false;
}
@@ -68,37 +67,43 @@ public final class BluetoothCodecStatus implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mCodecConfig, mCodecsLocalCapabilities,
mCodecsLocalCapabilities);
mCodecsLocalCapabilities);
}
@Override
public String toString() {
return "{mCodecConfig:" + mCodecConfig +
",mCodecsLocalCapabilities:" + Arrays.toString(mCodecsLocalCapabilities) +
",mCodecsSelectableCapabilities:" + Arrays.toString(mCodecsSelectableCapabilities) +
"}";
return "{mCodecConfig:" + mCodecConfig
+ ",mCodecsLocalCapabilities:" + Arrays.toString(mCodecsLocalCapabilities)
+ ",mCodecsSelectableCapabilities:" + Arrays.toString(mCodecsSelectableCapabilities)
+ "}";
}
@Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<BluetoothCodecStatus> CREATOR =
new Parcelable.Creator<BluetoothCodecStatus>() {
public BluetoothCodecStatus createFromParcel(Parcel in) {
final BluetoothCodecConfig codecConfig = in.readTypedObject(BluetoothCodecConfig.CREATOR);
final BluetoothCodecConfig[] codecsLocalCapabilities = in.createTypedArray(BluetoothCodecConfig.CREATOR);
final BluetoothCodecConfig[] codecsSelectableCapabilities = in.createTypedArray(BluetoothCodecConfig.CREATOR);
public BluetoothCodecStatus createFromParcel(Parcel in) {
final BluetoothCodecConfig codecConfig = in.readTypedObject(
BluetoothCodecConfig.CREATOR);
final BluetoothCodecConfig[] codecsLocalCapabilities = in.createTypedArray(
BluetoothCodecConfig.CREATOR);
final BluetoothCodecConfig[] codecsSelectableCapabilities = in.createTypedArray(
BluetoothCodecConfig.CREATOR);
return new BluetoothCodecStatus(codecConfig,
codecsLocalCapabilities,
codecsSelectableCapabilities);
}
public BluetoothCodecStatus[] newArray(int size) {
return new BluetoothCodecStatus[size];
}
};
return new BluetoothCodecStatus(codecConfig,
codecsLocalCapabilities,
codecsSelectableCapabilities);
}
public BluetoothCodecStatus[] newArray(int size) {
return new BluetoothCodecStatus[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeTypedObject(mCodecConfig, 0);
out.writeTypedArray(mCodecsLocalCapabilities, 0);

File diff suppressed because it is too large Load Diff

View File

@@ -48,11 +48,11 @@ public interface BluetoothDevicePicker {
* This intent contains below extra data:
* - {@link #EXTRA_NEED_AUTH} (boolean): if need authentication
* - {@link #EXTRA_FILTER_TYPE} (int): what kinds of device should be
* listed
* listed
* - {@link #EXTRA_LAUNCH_PACKAGE} (string): where(which package) this
* intent come from
* intent come from
* - {@link #EXTRA_LAUNCH_CLASS} (string): where(which class) this intent
* come from
* come from
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_LAUNCH =
@@ -64,8 +64,10 @@ public interface BluetoothDevicePicker {
public static final int FILTER_TYPE_AUDIO = 1;
/** Ask device picker to show BT devices that support Object Transfer */
public static final int FILTER_TYPE_TRANSFER = 2;
/** Ask device picker to show BT devices that support
* Personal Area Networking User (PANU) profile*/
/**
* Ask device picker to show BT devices that support
* Personal Area Networking User (PANU) profile
*/
public static final int FILTER_TYPE_PANU = 3;
/** Ask device picker to show BT devices that support Network Access Point (NAP) profile */
public static final int FILTER_TYPE_NAP = 4;

File diff suppressed because it is too large Load Diff

View File

@@ -19,19 +19,19 @@ package android.bluetooth;
/**
* This abstract class is used to implement {@link BluetoothGatt} callbacks.
*/
public abstract class BluetoothGattCallback{
public abstract class BluetoothGattCallback {
/**
* Callback triggered as result of {@link BluetoothGatt#setPreferredPhy}, or as a result of
* remote device changing the PHY.
*
* @param gatt GATT client
* @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param status Status of the PHY update operation.
* {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param status Status of the PHY update operation. {@link BluetoothGatt#GATT_SUCCESS} if the
* operation succeeds.
*/
public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
}
@@ -40,12 +40,12 @@ public abstract class BluetoothGattCallback{
* Callback triggered as result of {@link BluetoothGatt#readPhy}
*
* @param gatt GATT client
* @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param status Status of the PHY read operation.
* {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param status Status of the PHY read operation. {@link BluetoothGatt#GATT_SUCCESS} if the
* operation succeeds.
*/
public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
}
@@ -55,14 +55,13 @@ public abstract class BluetoothGattCallback{
* GATT server.
*
* @param gatt GATT client
* @param status Status of the connect or disconnect operation.
* {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param newState Returns the new connection state. Can be one of
* {@link BluetoothProfile#STATE_DISCONNECTED} or
* {@link BluetoothProfile#STATE_CONNECTED}
* @param status Status of the connect or disconnect operation. {@link
* BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param newState Returns the new connection state. Can be one of {@link
* BluetoothProfile#STATE_DISCONNECTED} or {@link BluetoothProfile#STATE_CONNECTED}
*/
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
int newState) {
}
/**
@@ -70,8 +69,8 @@ public abstract class BluetoothGattCallback{
* for the remote device have been updated, ie new services have been discovered.
*
* @param gatt GATT client invoked {@link BluetoothGatt#discoverServices}
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
* has been explored successfully.
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device has been explored
* successfully.
*/
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
}
@@ -80,13 +79,12 @@ public abstract class BluetoothGattCallback{
* Callback reporting the result of a characteristic read operation.
*
* @param gatt GATT client invoked {@link BluetoothGatt#readCharacteristic}
* @param characteristic Characteristic that was read from the associated
* remote device.
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
* was completed successfully.
* @param characteristic Characteristic that was read from the associated remote device.
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
* successfully.
*/
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
int status) {
int status) {
}
/**
@@ -99,58 +97,55 @@ public abstract class BluetoothGattCallback{
* the application must abort the reliable write transaction.
*
* @param gatt GATT client invoked {@link BluetoothGatt#writeCharacteristic}
* @param characteristic Characteristic that was written to the associated
* remote device.
* @param status The result of the write operation
* {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param characteristic Characteristic that was written to the associated remote device.
* @param status The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if the
* operation succeeds.
*/
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BluetoothGattCharacteristic characteristic, int status) {
}
/**
* Callback triggered as a result of a remote characteristic notification.
*
* @param gatt GATT client the characteristic is associated with
* @param characteristic Characteristic that has been updated as a result
* of a remote notification event.
* @param characteristic Characteristic that has been updated as a result of a remote
* notification event.
*/
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
BluetoothGattCharacteristic characteristic) {
}
/**
* Callback reporting the result of a descriptor read operation.
*
* @param gatt GATT client invoked {@link BluetoothGatt#readDescriptor}
* @param descriptor Descriptor that was read from the associated
* remote device.
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
* was completed successfully
* @param descriptor Descriptor that was read from the associated remote device.
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
* successfully
*/
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
int status) {
int status) {
}
/**
* Callback indicating the result of a descriptor write operation.
*
* @param gatt GATT client invoked {@link BluetoothGatt#writeDescriptor}
* @param descriptor Descriptor that was writte to the associated
* remote device.
* @param status The result of the write operation
* {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param descriptor Descriptor that was writte to the associated remote device.
* @param status The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if the
* operation succeeds.
*/
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
int status) {
int status) {
}
/**
* Callback invoked when a reliable write transaction has been completed.
*
* @param gatt GATT client invoked {@link BluetoothGatt#executeReliableWrite}
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write
* transaction was executed successfully
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write transaction was
* executed successfully
*/
public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
}
@@ -186,17 +181,17 @@ public abstract class BluetoothGattCallback{
* Callback indicating the connection parameters were updated.
*
* @param gatt GATT client involved
* @param interval Connection interval used on this connection, 1.25ms unit. Valid
* range is from 6 (7.5ms) to 3200 (4000ms).
* @param latency Slave latency for the connection in number of connection events. Valid
* range is from 0 to 499
* @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is
* from 10 (0.1s) to 3200 (32s)
* @param interval Connection interval used on this connection, 1.25ms unit. Valid range is from
* 6 (7.5ms) to 3200 (4000ms).
* @param latency Slave latency for the connection in number of connection events. Valid range
* is from 0 to 499
* @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is from 10
* (0.1s) to 3200 (32s)
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
* successfully
* successfully
* @hide
*/
public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout,
int status) {
int status) {
}
}

View File

@@ -16,8 +16,9 @@
package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelUuid;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -171,30 +172,35 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* The UUID of this characteristic.
*
* @hide
*/
protected UUID mUuid;
/**
* Instance ID for this characteristic.
*
* @hide
*/
protected int mInstance;
/**
* Characteristic properties.
*
* @hide
*/
protected int mProperties;
/**
* Characteristic permissions.
*
* @hide
*/
protected int mPermissions;
/**
* Key size (default = 16).
*
* @hide
*/
protected int mKeySize = 16;
@@ -202,18 +208,21 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* Write type for this characteristic.
* See WRITE_TYPE_* constants.
*
* @hide
*/
protected int mWriteType;
/**
* Back-reference to the service this characteristic belongs to.
*
* @hide
*/
protected BluetoothGattService mService;
/**
* The cached value of this characteristic.
*
* @hide
*/
protected byte[] mValue;
@@ -237,26 +246,28 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* Create a new BluetoothGattCharacteristic
*
* @hide
*/
/*package*/ BluetoothGattCharacteristic(BluetoothGattService service,
UUID uuid, int instanceId,
int properties, int permissions) {
UUID uuid, int instanceId,
int properties, int permissions) {
initCharacteristic(service, uuid, instanceId, properties, permissions);
}
/**
* Create a new BluetoothGattCharacteristic
*
* @hide
*/
public BluetoothGattCharacteristic(UUID uuid, int instanceId,
int properties, int permissions) {
int properties, int permissions) {
initCharacteristic(null, uuid, instanceId, properties, permissions);
}
private void initCharacteristic(BluetoothGattService service,
UUID uuid, int instanceId,
int properties, int permissions) {
UUID uuid, int instanceId,
int properties, int permissions) {
mUuid = uuid;
mInstance = instanceId;
mProperties = properties;
@@ -272,13 +283,12 @@ public class BluetoothGattCharacteristic implements Parcelable {
}
}
/**
* @hide
*/
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(new ParcelUuid(mUuid), 0);
out.writeInt(mInstance);
@@ -289,8 +299,8 @@ public class BluetoothGattCharacteristic implements Parcelable {
out.writeTypedList(mDescriptors);
}
public static final Parcelable.Creator<BluetoothGattCharacteristic> CREATOR
= new Parcelable.Creator<BluetoothGattCharacteristic>() {
public static final Parcelable.Creator<BluetoothGattCharacteristic> CREATOR =
new Parcelable.Creator<BluetoothGattCharacteristic>() {
public BluetoothGattCharacteristic createFromParcel(Parcel in) {
return new BluetoothGattCharacteristic(in);
}
@@ -301,7 +311,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
};
private BluetoothGattCharacteristic(Parcel in) {
mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
mInstance = in.readInt();
mProperties = in.readInt();
mPermissions = in.readInt();
@@ -313,7 +323,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
ArrayList<BluetoothGattDescriptor> descs =
in.createTypedArrayList(BluetoothGattDescriptor.CREATOR);
if (descs != null) {
for (BluetoothGattDescriptor desc: descs) {
for (BluetoothGattDescriptor desc : descs) {
desc.setCharacteristic(this);
mDescriptors.add(desc);
}
@@ -322,6 +332,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* Returns the desired key size.
*
* @hide
*/
public int getKeySize() {
@@ -343,12 +354,13 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* Get a descriptor by UUID and isntance id.
*
* @hide
*/
/*package*/ BluetoothGattDescriptor getDescriptor(UUID uuid, int instanceId) {
for(BluetoothGattDescriptor descriptor : mDescriptors) {
for (BluetoothGattDescriptor descriptor : mDescriptors) {
if (descriptor.getUuid().equals(uuid)
&& descriptor.getInstanceId() == instanceId) {
&& descriptor.getInstanceId() == instanceId) {
return descriptor;
}
}
@@ -357,6 +369,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* Returns the service this characteristic belongs to.
*
* @return The asscociated service
*/
public BluetoothGattService getService() {
@@ -365,6 +378,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* Sets the service associated with this device.
*
* @hide
*/
/*package*/ void setService(BluetoothGattService service) {
@@ -394,6 +408,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* Force the instance ID.
*
* @hide
*/
public void setInstanceId(int instanceId) {
@@ -437,11 +452,8 @@ public class BluetoothGattCharacteristic implements Parcelable {
* {@link BluetoothGatt#writeCharacteristic} function write this
* characteristic.
*
* @param writeType The write type to for this characteristic. Can be one
* of:
* {@link #WRITE_TYPE_DEFAULT},
* {@link #WRITE_TYPE_NO_RESPONSE} or
* {@link #WRITE_TYPE_SIGNED}.
* @param writeType The write type to for this characteristic. Can be one of: {@link
* #WRITE_TYPE_DEFAULT}, {@link #WRITE_TYPE_NO_RESPONSE} or {@link #WRITE_TYPE_SIGNED}.
*/
public void setWriteType(int writeType) {
mWriteType = writeType;
@@ -449,6 +461,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
/**
* Set the desired key size.
*
* @hide
*/
public void setKeySize(int keySize) {
@@ -468,11 +481,10 @@ public class BluetoothGattCharacteristic implements Parcelable {
* Returns a descriptor with a given UUID out of the list of
* descriptors for this characteristic.
*
* @return GATT descriptor object or null if no descriptor with the
* given UUID was found.
* @return GATT descriptor object or null if no descriptor with the given UUID was found.
*/
public BluetoothGattDescriptor getDescriptor(UUID uuid) {
for(BluetoothGattDescriptor descriptor : mDescriptors) {
for (BluetoothGattDescriptor descriptor : mDescriptors) {
if (descriptor.getUuid().equals(uuid)) {
return descriptor;
}
@@ -503,11 +515,9 @@ public class BluetoothGattCharacteristic implements Parcelable {
* characteristic value at the given offset are interpreted to generate the
* return value.
*
* @param formatType The format type used to interpret the characteristic
* value.
* @param formatType The format type used to interpret the characteristic value.
* @param offset Offset at which the integer value can be found.
* @return Cached value of the characteristic or null of offset exceeds
* value size.
* @return Cached value of the characteristic or null of offset exceeds value size.
*/
public Integer getIntValue(int formatType, int offset) {
if ((offset + getTypeLen(formatType)) > mValue.length) return null;
@@ -517,21 +527,21 @@ public class BluetoothGattCharacteristic implements Parcelable {
return unsignedByteToInt(mValue[offset]);
case FORMAT_UINT16:
return unsignedBytesToInt(mValue[offset], mValue[offset+1]);
return unsignedBytesToInt(mValue[offset], mValue[offset + 1]);
case FORMAT_UINT32:
return unsignedBytesToInt(mValue[offset], mValue[offset+1],
mValue[offset+2], mValue[offset+3]);
return unsignedBytesToInt(mValue[offset], mValue[offset + 1],
mValue[offset + 2], mValue[offset + 3]);
case FORMAT_SINT8:
return unsignedToSigned(unsignedByteToInt(mValue[offset]), 8);
case FORMAT_SINT16:
return unsignedToSigned(unsignedBytesToInt(mValue[offset],
mValue[offset+1]), 16);
mValue[offset + 1]), 16);
case FORMAT_SINT32:
return unsignedToSigned(unsignedBytesToInt(mValue[offset],
mValue[offset+1], mValue[offset+2], mValue[offset+3]), 32);
mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]), 32);
}
return null;
@@ -541,22 +551,21 @@ public class BluetoothGattCharacteristic implements Parcelable {
* Return the stored value of this characteristic.
* <p>See {@link #getValue} for details.
*
* @param formatType The format type used to interpret the characteristic
* value.
* @param formatType The format type used to interpret the characteristic value.
* @param offset Offset at which the float value can be found.
* @return Cached value of the characteristic at a given offset or null
* if the requested offset exceeds the value size.
* @return Cached value of the characteristic at a given offset or null if the requested offset
* exceeds the value size.
*/
public Float getFloatValue(int formatType, int offset) {
if ((offset + getTypeLen(formatType)) > mValue.length) return null;
switch (formatType) {
case FORMAT_SFLOAT:
return bytesToFloat(mValue[offset], mValue[offset+1]);
return bytesToFloat(mValue[offset], mValue[offset + 1]);
case FORMAT_FLOAT:
return bytesToFloat(mValue[offset], mValue[offset+1],
mValue[offset+2], mValue[offset+3]);
return bytesToFloat(mValue[offset], mValue[offset + 1],
mValue[offset + 2], mValue[offset + 3]);
}
return null;
@@ -572,7 +581,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
public String getStringValue(int offset) {
if (mValue == null || offset > mValue.length) return null;
byte[] strBytes = new byte[mValue.length - offset];
for (int i=0; i != (mValue.length-offset); ++i) strBytes[i] = mValue[offset+i];
for (int i = 0; i != (mValue.length - offset); ++i) strBytes[i] = mValue[offset + i];
return new String(strBytes);
}
@@ -585,8 +594,8 @@ public class BluetoothGattCharacteristic implements Parcelable {
* remote device.
*
* @param value New value for this characteristic
* @return true if the locally stored value has been set, false if the
* requested value could not be stored locally.
* @return true if the locally stored value has been set, false if the requested value could not
* be stored locally.
*/
public boolean setValue(byte[] value) {
mValue = value;
@@ -612,25 +621,25 @@ public class BluetoothGattCharacteristic implements Parcelable {
value = intToSignedBits(value, 8);
// Fall-through intended
case FORMAT_UINT8:
mValue[offset] = (byte)(value & 0xFF);
mValue[offset] = (byte) (value & 0xFF);
break;
case FORMAT_SINT16:
value = intToSignedBits(value, 16);
// Fall-through intended
case FORMAT_UINT16:
mValue[offset++] = (byte)(value & 0xFF);
mValue[offset] = (byte)((value >> 8) & 0xFF);
mValue[offset++] = (byte) (value & 0xFF);
mValue[offset] = (byte) ((value >> 8) & 0xFF);
break;
case FORMAT_SINT32:
value = intToSignedBits(value, 32);
// Fall-through intended
case FORMAT_UINT32:
mValue[offset++] = (byte)(value & 0xFF);
mValue[offset++] = (byte)((value >> 8) & 0xFF);
mValue[offset++] = (byte)((value >> 16) & 0xFF);
mValue[offset] = (byte)((value >> 24) & 0xFF);
mValue[offset++] = (byte) (value & 0xFF);
mValue[offset++] = (byte) ((value >> 8) & 0xFF);
mValue[offset++] = (byte) ((value >> 16) & 0xFF);
mValue[offset] = (byte) ((value >> 24) & 0xFF);
break;
default:
@@ -644,7 +653,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
* <p>See {@link #setValue(byte[])} for details.
*
* @param mantissa Mantissa for this characteristic
* @param exponent exponent value for this characteristic
* @param exponent exponent value for this characteristic
* @param formatType Float format type used to transform the value parameter
* @param offset Offset at which the value should be placed
* @return true if the locally stored value has been set
@@ -658,18 +667,18 @@ public class BluetoothGattCharacteristic implements Parcelable {
case FORMAT_SFLOAT:
mantissa = intToSignedBits(mantissa, 12);
exponent = intToSignedBits(exponent, 4);
mValue[offset++] = (byte)(mantissa & 0xFF);
mValue[offset] = (byte)((mantissa >> 8) & 0x0F);
mValue[offset] += (byte)((exponent & 0x0F) << 4);
mValue[offset++] = (byte) (mantissa & 0xFF);
mValue[offset] = (byte) ((mantissa >> 8) & 0x0F);
mValue[offset] += (byte) ((exponent & 0x0F) << 4);
break;
case FORMAT_FLOAT:
mantissa = intToSignedBits(mantissa, 24);
exponent = intToSignedBits(exponent, 8);
mValue[offset++] = (byte)(mantissa & 0xFF);
mValue[offset++] = (byte)((mantissa >> 8) & 0xFF);
mValue[offset++] = (byte)((mantissa >> 16) & 0xFF);
mValue[offset] += (byte)(exponent & 0xFF);
mValue[offset++] = (byte) (mantissa & 0xFF);
mValue[offset++] = (byte) ((mantissa >> 8) & 0xFF);
mValue[offset++] = (byte) ((mantissa >> 16) & 0xFF);
mValue[offset] += (byte) (exponent & 0xFF);
break;
default:
@@ -717,7 +726,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
*/
private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) {
return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
+ (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
+ (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
}
/**
@@ -725,9 +734,9 @@ public class BluetoothGattCharacteristic implements Parcelable {
*/
private float bytesToFloat(byte b0, byte b1) {
int mantissa = unsignedToSigned(unsignedByteToInt(b0)
+ ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
+ ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
return (float)(mantissa * Math.pow(10, exponent));
return (float) (mantissa * Math.pow(10, exponent));
}
/**
@@ -735,9 +744,9 @@ public class BluetoothGattCharacteristic implements Parcelable {
*/
private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
int mantissa = unsignedToSigned(unsignedByteToInt(b0)
+ (unsignedByteToInt(b1) << 8)
+ (unsignedByteToInt(b2) << 16), 24);
return (float)(mantissa * Math.pow(10, b3));
+ (unsignedByteToInt(b1) << 8)
+ (unsignedByteToInt(b2) << 16), 24);
return (float) (mantissa * Math.pow(10, b3));
}
/**
@@ -745,8 +754,8 @@ public class BluetoothGattCharacteristic implements Parcelable {
* signed value.
*/
private int unsignedToSigned(int unsigned, int size) {
if ((unsigned & (1 << size-1)) != 0) {
unsigned = -1 * ((1 << size-1) - (unsigned & ((1 << size-1) - 1)));
if ((unsigned & (1 << size - 1)) != 0) {
unsigned = -1 * ((1 << size - 1) - (unsigned & ((1 << size - 1) - 1)));
}
return unsigned;
}
@@ -756,7 +765,7 @@ public class BluetoothGattCharacteristic implements Parcelable {
*/
private int intToSignedBits(int i, int size) {
if (i < 0) {
i = (1 << size-1) + (i & ((1 << size-1) - 1));
i = (1 << size - 1) + (i & ((1 << size - 1) - 1));
}
return i;
}

View File

@@ -17,8 +17,9 @@
package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelUuid;
import android.os.Parcelable;
import java.util.UUID;
/**
@@ -89,30 +90,35 @@ public class BluetoothGattDescriptor implements Parcelable {
/**
* The UUID of this descriptor.
*
* @hide
*/
protected UUID mUuid;
/**
* Instance ID for this descriptor.
*
* @hide
*/
protected int mInstance;
/**
* Permissions for this descriptor
*
* @hide
*/
protected int mPermissions;
/**
* Back-reference to the characteristic this descriptor belongs to.
*
* @hide
*/
protected BluetoothGattCharacteristic mCharacteristic;
/**
* The value for this descriptor.
*
* @hide
*/
protected byte[] mValue;
@@ -137,7 +143,7 @@ public class BluetoothGattDescriptor implements Parcelable {
* @param permissions Permissions for this descriptor
*/
/*package*/ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
int instance, int permissions) {
int instance, int permissions) {
initDescriptor(characteristic, uuid, instance, permissions);
}
@@ -149,28 +155,27 @@ public class BluetoothGattDescriptor implements Parcelable {
}
private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
int instance, int permissions) {
int instance, int permissions) {
mCharacteristic = characteristic;
mUuid = uuid;
mInstance = instance;
mPermissions = permissions;
}
/**
* @hide
*/
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(new ParcelUuid(mUuid), 0);
out.writeInt(mInstance);
out.writeInt(mPermissions);
}
public static final Parcelable.Creator<BluetoothGattDescriptor> CREATOR
= new Parcelable.Creator<BluetoothGattDescriptor>() {
public static final Parcelable.Creator<BluetoothGattDescriptor> CREATOR =
new Parcelable.Creator<BluetoothGattDescriptor>() {
public BluetoothGattDescriptor createFromParcel(Parcel in) {
return new BluetoothGattDescriptor(in);
}
@@ -181,13 +186,14 @@ public class BluetoothGattDescriptor implements Parcelable {
};
private BluetoothGattDescriptor(Parcel in) {
mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
mInstance = in.readInt();
mPermissions = in.readInt();
}
/**
* Returns the characteristic this descriptor belongs to.
*
* @return The characteristic.
*/
public BluetoothGattCharacteristic getCharacteristic() {
@@ -196,6 +202,7 @@ public class BluetoothGattDescriptor implements Parcelable {
/**
* Set the back-reference to the associated characteristic
*
* @hide
*/
/*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
@@ -228,6 +235,7 @@ public class BluetoothGattDescriptor implements Parcelable {
/**
* Force the instance ID.
*
* @hide
*/
public void setInstanceId(int instanceId) {
@@ -266,8 +274,8 @@ public class BluetoothGattDescriptor implements Parcelable {
* remote device.
*
* @param value New value for this descriptor
* @return true if the locally stored value has been set, false if the
* requested value could not be stored locally.
* @return true if the locally stored value has been set, false if the requested value could not
* be stored locally.
*/
public boolean setValue(byte[] value) {
mValue = value;

View File

@@ -16,14 +16,14 @@
package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelUuid;
import java.util.ArrayList;
import java.util.List;
import android.os.Parcelable;
import java.util.UUID;
/**
* Represents a Bluetooth GATT Included Service
*
* @hide
*/
public class BluetoothGattIncludedService implements Parcelable {
@@ -52,18 +52,20 @@ public class BluetoothGattIncludedService implements Parcelable {
mServiceType = serviceType;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(new ParcelUuid(mUuid), 0);
out.writeInt(mInstanceId);
out.writeInt(mServiceType);
}
}
public static final Parcelable.Creator<BluetoothGattIncludedService> CREATOR
= new Parcelable.Creator<BluetoothGattIncludedService>() {
public static final Parcelable.Creator<BluetoothGattIncludedService> CREATOR =
new Parcelable.Creator<BluetoothGattIncludedService>() {
public BluetoothGattIncludedService createFromParcel(Parcel in) {
return new BluetoothGattIncludedService(in);
}
@@ -74,7 +76,7 @@ public class BluetoothGattIncludedService implements Parcelable {
};
private BluetoothGattIncludedService(Parcel in) {
mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
mInstanceId = in.readInt();
mServiceType = in.readInt();
}

View File

@@ -16,10 +16,6 @@
package android.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.util.Log;
@@ -60,300 +56,322 @@ public final class BluetoothGattServer implements BluetoothProfile {
* Bluetooth GATT interface callbacks
*/
private final IBluetoothGattServerCallback mBluetoothGattServerCallback =
new IBluetoothGattServerCallback.Stub() {
/**
* Application interface registered - app is ready to go
* @hide
*/
@Override
public void onServerRegistered(int status, int serverIf) {
if (DBG) Log.d(TAG, "onServerRegistered() - status=" + status
+ " serverIf=" + serverIf);
synchronized(mServerIfLock) {
if (mCallback != null) {
mServerIf = serverIf;
mServerIfLock.notify();
} else {
// registration timeout
Log.e(TAG, "onServerRegistered: mCallback is null");
new IBluetoothGattServerCallback.Stub() {
/**
* Application interface registered - app is ready to go
* @hide
*/
@Override
public void onServerRegistered(int status, int serverIf) {
if (DBG) {
Log.d(TAG, "onServerRegistered() - status=" + status
+ " serverIf=" + serverIf);
}
}
}
/**
* Server connection state changed
* @hide
*/
@Override
public void onServerConnectionState(int status, int serverIf,
boolean connected, String address) {
if (DBG) Log.d(TAG, "onServerConnectionState() - status=" + status
+ " serverIf=" + serverIf + " device=" + address);
try {
mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status,
connected ? BluetoothProfile.STATE_CONNECTED :
BluetoothProfile.STATE_DISCONNECTED);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
/**
* Service has been added
* @hide
*/
@Override
public void onServiceAdded(int status, BluetoothGattService service) {
if (DBG) Log.d(TAG, "onServiceAdded() - handle=" + service.getInstanceId()
+ " uuid=" + service.getUuid() + " status=" + status);
if (mPendingService == null)
return;
BluetoothGattService tmp = mPendingService;
mPendingService = null;
// Rewrite newly assigned handles to existing service.
tmp.setInstanceId(service.getInstanceId());
List<BluetoothGattCharacteristic> temp_chars = tmp.getCharacteristics();
List<BluetoothGattCharacteristic> svc_chars = service.getCharacteristics();
for (int i=0; i<svc_chars.size(); i++) {
BluetoothGattCharacteristic temp_char = temp_chars.get(i);
BluetoothGattCharacteristic svc_char = svc_chars.get(i);
temp_char.setInstanceId(svc_char.getInstanceId());
List<BluetoothGattDescriptor> temp_descs = temp_char.getDescriptors();
List<BluetoothGattDescriptor> svc_descs = svc_char.getDescriptors();
for (int j=0; j<svc_descs.size(); j++) {
temp_descs.get(j).setInstanceId(svc_descs.get(j).getInstanceId());
synchronized (mServerIfLock) {
if (mCallback != null) {
mServerIf = serverIf;
mServerIfLock.notify();
} else {
// registration timeout
Log.e(TAG, "onServerRegistered: mCallback is null");
}
}
}
mServices.add(tmp);
try {
mCallback.onServiceAdded((int)status, tmp);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
/**
* Remote client characteristic read request.
* @hide
*/
@Override
public void onCharacteristicReadRequest(String address, int transId,
int offset, boolean isLong, int handle) {
if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
if (characteristic == null) {
Log.w(TAG, "onCharacteristicReadRequest() no char for handle " + handle);
return;
/**
* Server connection state changed
* @hide
*/
@Override
public void onServerConnectionState(int status, int serverIf,
boolean connected, String address) {
if (DBG) {
Log.d(TAG, "onServerConnectionState() - status=" + status
+ " serverIf=" + serverIf + " device=" + address);
}
try {
mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status,
connected ? BluetoothProfile.STATE_CONNECTED :
BluetoothProfile.STATE_DISCONNECTED);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
try {
mCallback.onCharacteristicReadRequest(device, transId, offset, characteristic);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
/**
* Service has been added
* @hide
*/
@Override
public void onServiceAdded(int status, BluetoothGattService service) {
if (DBG) {
Log.d(TAG, "onServiceAdded() - handle=" + service.getInstanceId()
+ " uuid=" + service.getUuid() + " status=" + status);
}
/**
* Remote client descriptor read request.
* @hide
*/
@Override
public void onDescriptorReadRequest(String address, int transId,
int offset, boolean isLong, int handle) {
if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
if (mPendingService == null) {
return;
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
if (descriptor == null) {
Log.w(TAG, "onDescriptorReadRequest() no desc for handle " + handle);
return;
BluetoothGattService tmp = mPendingService;
mPendingService = null;
// Rewrite newly assigned handles to existing service.
tmp.setInstanceId(service.getInstanceId());
List<BluetoothGattCharacteristic> temp_chars = tmp.getCharacteristics();
List<BluetoothGattCharacteristic> svc_chars = service.getCharacteristics();
for (int i = 0; i < svc_chars.size(); i++) {
BluetoothGattCharacteristic temp_char = temp_chars.get(i);
BluetoothGattCharacteristic svc_char = svc_chars.get(i);
temp_char.setInstanceId(svc_char.getInstanceId());
List<BluetoothGattDescriptor> temp_descs = temp_char.getDescriptors();
List<BluetoothGattDescriptor> svc_descs = svc_char.getDescriptors();
for (int j = 0; j < svc_descs.size(); j++) {
temp_descs.get(j).setInstanceId(svc_descs.get(j).getInstanceId());
}
}
mServices.add(tmp);
try {
mCallback.onServiceAdded((int) status, tmp);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
try {
mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
/**
* Remote client characteristic read request.
* @hide
*/
@Override
public void onCharacteristicReadRequest(String address, int transId,
int offset, boolean isLong, int handle) {
if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
/**
* Remote client characteristic write request.
* @hide
*/
@Override
public void onCharacteristicWriteRequest(String address, int transId,
int offset, int length, boolean isPrep, boolean needRsp,
int handle, byte[] value) {
if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - handle=" + handle);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
if (characteristic == null) {
Log.w(TAG, "onCharacteristicReadRequest() no char for handle " + handle);
return;
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
if (characteristic == null) {
Log.w(TAG, "onCharacteristicWriteRequest() no char for handle " + handle);
return;
try {
mCallback.onCharacteristicReadRequest(device, transId, offset,
characteristic);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
try {
mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
isPrep, needRsp, offset, value);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
/**
* Remote client descriptor read request.
* @hide
*/
@Override
public void onDescriptorReadRequest(String address, int transId,
int offset, boolean isLong, int handle) {
if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
if (descriptor == null) {
Log.w(TAG, "onDescriptorReadRequest() no desc for handle " + handle);
return;
}
try {
mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
}
/**
* Remote client characteristic write request.
* @hide
*/
@Override
public void onCharacteristicWriteRequest(String address, int transId,
int offset, int length, boolean isPrep, boolean needRsp,
int handle, byte[] value) {
if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - handle=" + handle);
/**
* Remote client descriptor write request.
* @hide
*/
@Override
public void onDescriptorWriteRequest(String address, int transId, int offset,
int length, boolean isPrep, boolean needRsp, int handle, byte[] value) {
if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - handle=" + handle);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
if (characteristic == null) {
Log.w(TAG, "onCharacteristicWriteRequest() no char for handle " + handle);
return;
}
try {
mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
isPrep, needRsp, offset, value);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
if (descriptor == null) {
Log.w(TAG, "onDescriptorWriteRequest() no desc for handle " + handle);
return;
}
try {
mCallback.onDescriptorWriteRequest(device, transId, descriptor,
isPrep, needRsp, offset, value);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
/**
* Remote client descriptor write request.
* @hide
*/
@Override
public void onDescriptorWriteRequest(String address, int transId, int offset,
int length, boolean isPrep, boolean needRsp, int handle, byte[] value) {
if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - handle=" + handle);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
if (descriptor == null) {
Log.w(TAG, "onDescriptorWriteRequest() no desc for handle " + handle);
return;
}
try {
mCallback.onDescriptorWriteRequest(device, transId, descriptor,
isPrep, needRsp, offset, value);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
}
/**
* Execute pending writes.
* @hide
*/
@Override
public void onExecuteWrite(String address, int transId,
boolean execWrite) {
if (DBG) Log.d(TAG, "onExecuteWrite() - "
+ "device=" + address + ", transId=" + transId
+ "execWrite=" + execWrite);
/**
* Execute pending writes.
* @hide
*/
@Override
public void onExecuteWrite(String address, int transId,
boolean execWrite) {
if (DBG) {
Log.d(TAG, "onExecuteWrite() - "
+ "device=" + address + ", transId=" + transId
+ "execWrite=" + execWrite);
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
try {
mCallback.onExecuteWrite(device, transId, execWrite);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
try {
mCallback.onExecuteWrite(device, transId, execWrite);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
}
/**
* A notification/indication has been sent.
* @hide
*/
@Override
public void onNotificationSent(String address, int status) {
if (VDBG) Log.d(TAG, "onNotificationSent() - "
+ "device=" + address + ", status=" + status);
/**
* A notification/indication has been sent.
* @hide
*/
@Override
public void onNotificationSent(String address, int status) {
if (VDBG) {
Log.d(TAG, "onNotificationSent() - "
+ "device=" + address + ", status=" + status);
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
try {
mCallback.onNotificationSent(device, status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
try {
mCallback.onNotificationSent(device, status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
}
/**
* The MTU for a connection has changed
* @hide
*/
@Override
public void onMtuChanged(String address, int mtu) {
if (DBG) Log.d(TAG, "onMtuChanged() - "
+ "device=" + address + ", mtu=" + mtu);
/**
* The MTU for a connection has changed
* @hide
*/
@Override
public void onMtuChanged(String address, int mtu) {
if (DBG) {
Log.d(TAG, "onMtuChanged() - "
+ "device=" + address + ", mtu=" + mtu);
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
try {
mCallback.onMtuChanged(device, mtu);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
try {
mCallback.onMtuChanged(device, mtu);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
}
/**
* The PHY for a connection was updated
* @hide
*/
@Override
public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
if (DBG) Log.d(TAG, "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
+ ", rxPHy=" + rxPhy);
/**
* The PHY for a connection was updated
* @hide
*/
@Override
public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
if (DBG) {
Log.d(TAG,
"onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
+ ", rxPHy=" + rxPhy);
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
try {
mCallback.onPhyUpdate(device, txPhy, rxPhy, status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
try {
mCallback.onPhyUpdate(device, txPhy, rxPhy, status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
}
/**
* The PHY for a connection was read
* @hide
*/
@Override
public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
if (DBG) Log.d(TAG, "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
+ ", rxPHy=" + rxPhy);
/**
* The PHY for a connection was read
* @hide
*/
@Override
public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
if (DBG) {
Log.d(TAG,
"onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
+ ", rxPHy=" + rxPhy);
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
try {
mCallback.onPhyRead(device, txPhy, rxPhy, status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
try {
mCallback.onPhyRead(device, txPhy, rxPhy, status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
}
/**
* Callback invoked when the given connection is updated
* @hide
*/
@Override
public void onConnectionUpdated(String address, int interval, int latency,
int timeout, int status) {
if (DBG) Log.d(TAG, "onConnectionUpdated() - Device=" + address +
" interval=" + interval + " latency=" + latency +
" timeout=" + timeout + " status=" + status);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
/**
* Callback invoked when the given connection is updated
* @hide
*/
@Override
public void onConnectionUpdated(String address, int interval, int latency,
int timeout, int status) {
if (DBG) {
Log.d(TAG, "onConnectionUpdated() - Device=" + address
+ " interval=" + interval + " latency=" + latency
+ " timeout=" + timeout + " status=" + status);
}
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (device == null) return;
try {
mCallback.onConnectionUpdated(device, interval, latency,
timeout, status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
try {
mCallback.onConnectionUpdated(device, interval, latency,
timeout, status);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
}
}
}
};
};
/**
* Create a BluetoothGattServer proxy object.
@@ -369,13 +387,15 @@ public final class BluetoothGattServer implements BluetoothProfile {
/**
* Returns a characteristic with given handle.
*
* @hide
*/
/*package*/ BluetoothGattCharacteristic getCharacteristicByHandle(int handle) {
for(BluetoothGattService svc : mServices) {
for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
if (charac.getInstanceId() == handle)
for (BluetoothGattService svc : mServices) {
for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
if (charac.getInstanceId() == handle) {
return charac;
}
}
}
return null;
@@ -383,14 +403,16 @@ public final class BluetoothGattServer implements BluetoothProfile {
/**
* Returns a descriptor with given handle.
*
* @hide
*/
/*package*/ BluetoothGattDescriptor getDescriptorByHandle(int handle) {
for(BluetoothGattService svc : mServices) {
for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
for(BluetoothGattDescriptor desc : charac.getDescriptors()) {
if (desc.getInstanceId() == handle)
for (BluetoothGattService svc : mServices) {
for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
for (BluetoothGattDescriptor desc : charac.getDescriptors()) {
if (desc.getInstanceId() == handle) {
return desc;
}
}
}
}
@@ -416,10 +438,9 @@ public final class BluetoothGattServer implements BluetoothProfile {
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param callback GATT callback handler that will receive asynchronous
* callbacks.
* @return true, the callback will be called to notify success or failure,
* false on immediate error
* @param callback GATT callback handler that will receive asynchronous callbacks.
* @return true, the callback will be called to notify success or failure, false on immediate
* error
*/
/*package*/ boolean registerCallback(BluetoothGattServerCallback callback) {
if (DBG) Log.d(TAG, "registerCallback()");
@@ -430,7 +451,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
UUID uuid = UUID.randomUUID();
if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid);
synchronized(mServerIfLock) {
synchronized (mServerIfLock) {
if (mCallback != null) {
Log.e(TAG, "App can register callback only once");
return false;
@@ -440,7 +461,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
mCallback = null;
return false;
}
@@ -473,19 +494,20 @@ public final class BluetoothGattServer implements BluetoothProfile {
mService.unregisterServer(mServerIf);
mServerIf = 0;
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
/**
* Returns a service by UUID, instance and type.
*
* @hide
*/
/*package*/ BluetoothGattService getService(UUID uuid, int instanceId, int type) {
for(BluetoothGattService svc : mServices) {
if (svc.getType() == type &&
svc.getInstanceId() == instanceId &&
svc.getUuid().equals(uuid)) {
for (BluetoothGattService svc : mServices) {
if (svc.getType() == type
&& svc.getInstanceId() == instanceId
&& svc.getUuid().equals(uuid)) {
return svc;
}
}
@@ -509,20 +531,22 @@ public final class BluetoothGattServer implements BluetoothProfile {
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param autoConnect Whether to directly connect to the remote device (false)
* or to automatically connect as soon as the remote
* device becomes available (true).
* @param autoConnect Whether to directly connect to the remote device (false) or to
* automatically connect as soon as the remote device becomes available (true).
* @return true, if the connection attempt was initiated successfully
*/
public boolean connect(BluetoothDevice device, boolean autoConnect) {
if (DBG) Log.d(TAG, "connect() - device: " + device.getAddress() + ", auto: " + autoConnect);
if (DBG) {
Log.d(TAG,
"connect() - device: " + device.getAddress() + ", auto: " + autoConnect);
}
if (mService == null || mServerIf == 0) return false;
try {
mService.serverConnect(mServerIf, device.getAddress(),
autoConnect ? false : true,mTransport); // autoConnect is inverse of "isDirect"
// autoConnect is inverse of "isDirect"
mService.serverConnect(mServerIf, device.getAddress(), !autoConnect, mTransport);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
return false;
}
@@ -544,35 +568,34 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mService.serverDisconnect(mServerIf, device.getAddress());
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
/**
* Set the preferred connection PHY for this app. Please note that this is just a
* recommendation, whether the PHY change will happen depends on other applications peferences,
* local and remote controller capabilities. Controller can override these settings.
* <p>
* {@link BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even
* if no PHY change happens. It is also triggered when remote device updates the PHY.
* local and remote controller capabilities. Controller can override these settings. <p> {@link
* BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even if
* no PHY change happens. It is also triggered when remote device updates the PHY.
*
* @param device The remote device to send this response to
* @param txPhy preferred transmitter PHY. Bitwise OR of any of
* {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
* and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
* @param rxPhy preferred receiver PHY. Bitwise OR of any of
* {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
* and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
* @param txPhy preferred transmitter PHY. Bitwise OR of any of {@link
* BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
* BluetoothDevice#PHY_LE_CODED_MASK}.
* @param rxPhy preferred receiver PHY. Bitwise OR of any of {@link
* BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
* BluetoothDevice#PHY_LE_CODED_MASK}.
* @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one
* of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED},
* {@link BluetoothDevice#PHY_OPTION_S2} or {@link BluetoothDevice#PHY_OPTION_S8}
* of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or
* {@link BluetoothDevice#PHY_OPTION_S8}
*/
public void setPreferredPhy(BluetoothDevice device, int txPhy, int rxPhy, int phyOptions) {
try {
mService.serverSetPreferredPhy(mServerIf, device.getAddress(), txPhy, rxPhy,
phyOptions);
phyOptions);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -586,7 +609,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mService.serverReadPhy(mServerIf, device.getAddress());
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -597,10 +620,10 @@ public final class BluetoothGattServer implements BluetoothProfile {
* is received by one of these callback methods:
*
* <ul>
* <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest}
* <li>{@link BluetoothGattServerCallback#onCharacteristicWriteRequest}
* <li>{@link BluetoothGattServerCallback#onDescriptorReadRequest}
* <li>{@link BluetoothGattServerCallback#onDescriptorWriteRequest}
* <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest}
* <li>{@link BluetoothGattServerCallback#onCharacteristicWriteRequest}
* <li>{@link BluetoothGattServerCallback#onDescriptorReadRequest}
* <li>{@link BluetoothGattServerCallback#onDescriptorWriteRequest}
* </ul>
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -612,15 +635,15 @@ public final class BluetoothGattServer implements BluetoothProfile {
* @param value The value of the attribute that was read/written (optional)
*/
public boolean sendResponse(BluetoothDevice device, int requestId,
int status, int offset, byte[] value) {
int status, int offset, byte[] value) {
if (VDBG) Log.d(TAG, "sendResponse() - device: " + device.getAddress());
if (mService == null || mServerIf == 0) return false;
try {
mService.sendResponse(mServerIf, device.getAddress(), requestId,
status, offset, value);
status, offset, value);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
return false;
}
return true;
@@ -639,13 +662,13 @@ public final class BluetoothGattServer implements BluetoothProfile {
*
* @param device The remote device to receive the notification/indication
* @param characteristic The local characteristic that has been updated
* @param confirm true to request confirmation from the client (indication),
* false to send a notification
* @throws IllegalArgumentException
* @param confirm true to request confirmation from the client (indication), false to send a
* notification
* @return true, if the notification has been triggered successfully
* @throws IllegalArgumentException
*/
public boolean notifyCharacteristicChanged(BluetoothDevice device,
BluetoothGattCharacteristic characteristic, boolean confirm) {
BluetoothGattCharacteristic characteristic, boolean confirm) {
if (VDBG) Log.d(TAG, "notifyCharacteristicChanged() - device: " + device.getAddress());
if (mService == null || mServerIf == 0) return false;
@@ -662,7 +685,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
characteristic.getInstanceId(), confirm,
characteristic.getValue());
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
return false;
}
@@ -680,8 +703,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param service Service to be added to the list of services provided
* by this device.
* @param service Service to be added to the list of services provided by this device.
* @return true, if the service has been added successfully
*/
public boolean addService(BluetoothGattService service) {
@@ -693,7 +715,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mService.addService(mServerIf, service);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
return false;
}
@@ -713,14 +735,14 @@ public final class BluetoothGattServer implements BluetoothProfile {
if (mService == null || mServerIf == 0) return false;
BluetoothGattService intService = getService(service.getUuid(),
service.getInstanceId(), service.getType());
service.getInstanceId(), service.getType());
if (intService == null) return false;
try {
mService.removeService(mServerIf, service.getInstanceId());
mServices.remove(intService);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
return false;
}
@@ -739,7 +761,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
mService.clearServices(mServerIf);
mServices.clear();
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -751,8 +773,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return List of services. Returns an empty list
* if no services have been added yet.
* @return List of services. Returns an empty list if no services have been added yet.
*/
public List<BluetoothGattService> getServices() {
return mServices;
@@ -768,8 +789,8 @@ public final class BluetoothGattServer implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param uuid UUID of the requested service
* @return BluetoothGattService if supported, or null if the requested
* service is not offered by this device.
* @return BluetoothGattService if supported, or null if the requested service is not offered by
* this device.
*/
public BluetoothGattService getService(UUID uuid) {
for (BluetoothGattService service : mServices) {
@@ -801,8 +822,8 @@ public final class BluetoothGattServer implements BluetoothProfile {
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
throw new UnsupportedOperationException
("Use BluetoothManager#getConnectedDevices instead.");
throw new UnsupportedOperationException(
"Use BluetoothManager#getConnectedDevices instead.");
}
/**
@@ -814,7 +835,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
throw new UnsupportedOperationException
("Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
throw new UnsupportedOperationException(
"Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
}
}

View File

@@ -16,8 +16,6 @@
package android.bluetooth;
import android.bluetooth.BluetoothDevice;
/**
* This abstract class is used to implement {@link BluetoothGattServer} callbacks.
*/
@@ -28,19 +26,18 @@ public abstract class BluetoothGattServerCallback {
*
* @param device Remote device that has been connected or disconnected.
* @param status Status of the connect or disconnect operation.
* @param newState Returns the new connection state. Can be one of
* {@link BluetoothProfile#STATE_DISCONNECTED} or
* {@link BluetoothProfile#STATE_CONNECTED}
* @param newState Returns the new connection state. Can be one of {@link
* BluetoothProfile#STATE_DISCONNECTED} or {@link BluetoothProfile#STATE_CONNECTED}
*/
public void onConnectionStateChange(BluetoothDevice device, int status,
int newState) {
int newState) {
}
/**
* Indicates whether a local service has been added successfully.
*
* @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the service
* was added successfully.
* @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the service was added
* successfully.
* @param service The service that has been added
*/
public void onServiceAdded(int status, BluetoothGattService service) {
@@ -58,7 +55,7 @@ public abstract class BluetoothGattServerCallback {
* @param characteristic Characteristic to be read
*/
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
int offset, BluetoothGattCharacteristic characteristic) {
int offset, BluetoothGattCharacteristic characteristic) {
}
/**
@@ -70,16 +67,15 @@ public abstract class BluetoothGattServerCallback {
* @param device The remote device that has requested the write operation
* @param requestId The Id of the request
* @param characteristic Characteristic to be written to.
* @param preparedWrite true, if this write operation should be queued for
* later execution.
* @param preparedWrite true, if this write operation should be queued for later execution.
* @param responseNeeded true, if the remote device requires a response
* @param offset The offset given for the value
* @param value The value the client wants to assign to the characteristic
*/
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
BluetoothGattCharacteristic characteristic,
boolean preparedWrite, boolean responseNeeded,
int offset, byte[] value) {
BluetoothGattCharacteristic characteristic,
boolean preparedWrite, boolean responseNeeded,
int offset, byte[] value) {
}
/**
@@ -94,7 +90,7 @@ public abstract class BluetoothGattServerCallback {
* @param descriptor Descriptor to be read
*/
public void onDescriptorReadRequest(BluetoothDevice device, int requestId,
int offset, BluetoothGattDescriptor descriptor) {
int offset, BluetoothGattDescriptor descriptor) {
}
/**
@@ -106,16 +102,15 @@ public abstract class BluetoothGattServerCallback {
* @param device The remote device that has requested the write operation
* @param requestId The Id of the request
* @param descriptor Descriptor to be written to.
* @param preparedWrite true, if this write operation should be queued for
* later execution.
* @param preparedWrite true, if this write operation should be queued for later execution.
* @param responseNeeded true, if the remote device requires a response
* @param offset The offset given for the value
* @param value The value the client wants to assign to the descriptor
*/
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
BluetoothGattDescriptor descriptor,
boolean preparedWrite, boolean responseNeeded,
int offset, byte[] value) {
BluetoothGattDescriptor descriptor,
boolean preparedWrite, boolean responseNeeded,
int offset, byte[] value) {
}
/**
@@ -126,8 +121,7 @@ public abstract class BluetoothGattServerCallback {
*
* @param device The remote device that has requested the write operations
* @param requestId The Id of the request
* @param execute Whether the pending writes should be executed (true) or
* cancelled (false)
* @param execute Whether the pending writes should be executed (true) or cancelled (false)
*/
public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
}
@@ -163,12 +157,12 @@ public abstract class BluetoothGattServerCallback {
* of remote device changing the PHY.
*
* @param device The remote device
* @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param status Status of the PHY update operation.
* {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param status Status of the PHY update operation. {@link BluetoothGatt#GATT_SUCCESS} if the
* operation succeeds.
*/
public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
}
@@ -177,12 +171,12 @@ public abstract class BluetoothGattServerCallback {
* Callback triggered as result of {@link BluetoothGattServer#readPhy}
*
* @param device The remote device that requested the PHY read
* @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param status Status of the PHY read operation.
* {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param status Status of the PHY read operation. {@link BluetoothGatt#GATT_SUCCESS} if the
* operation succeeds.
*/
public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
}
@@ -190,19 +184,19 @@ public abstract class BluetoothGattServerCallback {
/**
* Callback indicating the connection parameters were updated.
*
* @param device The remote device involved
* @param interval Connection interval used on this connection, 1.25ms unit. Valid
* range is from 6 (7.5ms) to 3200 (4000ms).
* @param latency Slave latency for the connection in number of connection events. Valid
* range is from 0 to 499
* @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is
* from 10 (0.1s) to 3200 (32s)
* @param gatt The remote device involved
* @param interval Connection interval used on this connection, 1.25ms unit. Valid range is from
* 6 (7.5ms) to 3200 (4000ms).
* @param latency Slave latency for the connection in number of connection events. Valid range
* is from 0 to 499
* @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is from 10
* (0.1s) to 3200 (32s)
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
* successfully
* successfully
* @hide
*/
public void onConnectionUpdated(BluetoothDevice gatt, int interval, int latency, int timeout,
int status) {
int status) {
}
}

View File

@@ -16,8 +16,9 @@
package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelUuid;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -44,30 +45,35 @@ public class BluetoothGattService implements Parcelable {
/**
* The remote device his service is associated with.
* This applies to client applications only.
*
* @hide
*/
protected BluetoothDevice mDevice;
/**
* The UUID of this service.
*
* @hide
*/
protected UUID mUuid;
/**
* Instance ID for this service.
*
* @hide
*/
protected int mInstanceId;
/**
* Handle counter override (for conformance testing).
*
* @hide
*/
protected int mHandles = 0;
/**
* Service type (Primary/Secondary).
*
* @hide
*/
protected int mServiceType;
@@ -93,8 +99,8 @@ public class BluetoothGattService implements Parcelable {
*
* @param uuid The UUID for this service
* @param serviceType The type of this service,
* {@link BluetoothGattService#SERVICE_TYPE_PRIMARY} or
* {@link BluetoothGattService#SERVICE_TYPE_SECONDARY}
* {@link BluetoothGattService#SERVICE_TYPE_PRIMARY}
* or {@link BluetoothGattService#SERVICE_TYPE_SECONDARY}
*/
public BluetoothGattService(UUID uuid, int serviceType) {
mDevice = null;
@@ -107,10 +113,11 @@ public class BluetoothGattService implements Parcelable {
/**
* Create a new BluetoothGattService
*
* @hide
*/
/*package*/ BluetoothGattService(BluetoothDevice device, UUID uuid,
int instanceId, int serviceType) {
int instanceId, int serviceType) {
mDevice = device;
mUuid = uuid;
mInstanceId = instanceId;
@@ -121,6 +128,7 @@ public class BluetoothGattService implements Parcelable {
/**
* Create a new BluetoothGattService
*
* @hide
*/
public BluetoothGattService(UUID uuid, int instanceId, int serviceType) {
@@ -148,15 +156,15 @@ public class BluetoothGattService implements Parcelable {
ArrayList<BluetoothGattIncludedService> includedServices =
new ArrayList<BluetoothGattIncludedService>(mIncludedServices.size());
for(BluetoothGattService s : mIncludedServices) {
for (BluetoothGattService s : mIncludedServices) {
includedServices.add(new BluetoothGattIncludedService(s.getUuid(),
s.getInstanceId(), s.getType()));
s.getInstanceId(), s.getType()));
}
out.writeTypedList(includedServices);
}
}
public static final Parcelable.Creator<BluetoothGattService> CREATOR
= new Parcelable.Creator<BluetoothGattService>() {
public static final Parcelable.Creator<BluetoothGattService> CREATOR =
new Parcelable.Creator<BluetoothGattService>() {
public BluetoothGattService createFromParcel(Parcel in) {
return new BluetoothGattService(in);
}
@@ -167,7 +175,7 @@ public class BluetoothGattService implements Parcelable {
};
private BluetoothGattService(Parcel in) {
mUuid = ((ParcelUuid)in.readParcelable(null)).getUuid();
mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
mInstanceId = in.readInt();
mServiceType = in.readInt();
@@ -189,13 +197,14 @@ public class BluetoothGattService implements Parcelable {
if (chrcs != null) {
for (BluetoothGattIncludedService isvc : inclSvcs) {
mIncludedServices.add(new BluetoothGattService(null, isvc.getUuid(),
isvc.getInstanceId(), isvc.getType()));
isvc.getInstanceId(), isvc.getType()));
}
}
}
/**
* Returns the device associated with this service.
*
* @hide
*/
/*package*/ BluetoothDevice getDevice() {
@@ -204,10 +213,11 @@ public class BluetoothGattService implements Parcelable {
/**
* Returns the device associated with this service.
*
* @hide
*/
/*package*/ void setDevice(BluetoothDevice device) {
this.mDevice = device;
mDevice = device;
}
/**
@@ -237,19 +247,22 @@ public class BluetoothGattService implements Parcelable {
/**
* Get characteristic by UUID and instanceId.
*
* @hide
*/
/*package*/ BluetoothGattCharacteristic getCharacteristic(UUID uuid, int instanceId) {
for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
if (uuid.equals(characteristic.getUuid())
&& characteristic.getInstanceId() == instanceId)
&& characteristic.getInstanceId() == instanceId) {
return characteristic;
}
}
return null;
}
/**
* Force the instance ID.
*
* @hide
*/
public void setInstanceId(int instanceId) {
@@ -258,6 +271,7 @@ public class BluetoothGattService implements Parcelable {
/**
* Get the handle count override (conformance testing.
*
* @hide
*/
/*package*/ int getHandles() {
@@ -267,6 +281,7 @@ public class BluetoothGattService implements Parcelable {
/**
* Force the number of handles to reserve for this service.
* This is needed for conformance testing only.
*
* @hide
*/
public void setHandles(int handles) {
@@ -275,6 +290,7 @@ public class BluetoothGattService implements Parcelable {
/**
* Add an included service to the internal map.
*
* @hide
*/
public void addIncludedService(BluetoothGattService includedService) {
@@ -313,8 +329,7 @@ public class BluetoothGattService implements Parcelable {
/**
* Get the list of included GATT services for this service.
*
* @return List of included services or empty list if no included services
* were discovered.
* @return List of included services or empty list if no included services were discovered.
*/
public List<BluetoothGattService> getIncludedServices() {
return mIncludedServices;
@@ -341,30 +356,33 @@ public class BluetoothGattService implements Parcelable {
* UUID, the first instance of a characteristic with the given UUID
* is returned.
*
* @return GATT characteristic object or null if no characteristic with the
* given UUID was found.
* @return GATT characteristic object or null if no characteristic with the given UUID was
* found.
*/
public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
if (uuid.equals(characteristic.getUuid()))
for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
if (uuid.equals(characteristic.getUuid())) {
return characteristic;
}
}
return null;
}
/**
* Returns whether the uuid of the service should be advertised.
*
* @hide
*/
public boolean isAdvertisePreferred() {
return mAdvertisePreferred;
return mAdvertisePreferred;
}
/**
* Set whether the service uuid should be advertised.
*
* @hide
*/
public void setAdvertisePreferred(boolean advertisePreferred) {
this.mAdvertisePreferred = advertisePreferred;
mAdvertisePreferred = advertisePreferred;
}
}

View File

@@ -56,9 +56,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
* {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
@@ -69,7 +69,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
/**
* Intent used to broadcast the change in the Audio Connection state of the
@@ -77,9 +77,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
* {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED},
@@ -89,7 +89,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_AUDIO_STATE_CHANGED =
"android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
"android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
/**
@@ -98,19 +98,19 @@ public final class BluetoothHeadset implements BluetoothProfile {
*
* <p>This intent will have 4 extras and 1 category.
* <ul>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Bluetooth Device
* </li>
* <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD} - The vendor
* specific command </li>
* <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT
* command type which can be one of {@link #AT_CMD_TYPE_READ},
* {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET},
* {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li>
* <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command
* arguments. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Bluetooth Device
* </li>
* <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD} - The vendor
* specific command </li>
* <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT
* command type which can be one of {@link #AT_CMD_TYPE_READ},
* {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET},
* {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li>
* <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command
* arguments. </li>
* </ul>
*
*<p> The category is the Company ID of the vendor defining the
* <p> The category is the Company ID of the vendor defining the
* vendor-specific command. {@link BluetoothAssignedNumbers}
*
* For example, for Plantronics specific events
@@ -118,9 +118,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
*
* <p> For example, an AT+XEVENT=foo,3 will get translated into
* <ul>
* <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li>
* <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li>
* <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li>
* <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li>
* <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li>
* <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li>
* </ul>
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission
* to receive.
@@ -191,7 +191,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* The intent category to be used with {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
* for the companyId
*/
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY =
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY =
"android.bluetooth.headset.intent.category.companyid";
/**
@@ -201,12 +201,14 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* A vendor-specific AT command
*
* @hide
*/
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XAPL = "+XAPL";
/**
* A vendor-specific AT command
*
* @hide
*/
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV = "+IPHONEACCEV";
@@ -214,18 +216,21 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* Battery level indicator associated with
* {@link #VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV}
*
* @hide
*/
public static final int VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL = 1;
/**
* A vendor-specific AT command
*
* @hide
*/
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT = "+XEVENT";
/**
* Battery level indicator associated with {@link #VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT}
*
* @hide
*/
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL = "BATTERY";
@@ -258,17 +263,18 @@ public final class BluetoothHeadset implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_HF_INDICATORS_IND_ID} - The Assigned number of headset Indicator which
* is supported by the headset ( as indicated by AT+BIND command in the SLC
* sequence) or whose value is changed (indicated by AT+BIEV command) </li>
* <li> {@link #EXTRA_HF_INDICATORS_IND_VALUE} - Updated value of headset indicator. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - Remote device. </li>
* <li> {@link #EXTRA_HF_INDICATORS_IND_ID} - The Assigned number of headset Indicator which
* is supported by the headset ( as indicated by AT+BIND command in the SLC
* sequence) or whose value is changed (indicated by AT+BIEV command) </li>
* <li> {@link #EXTRA_HF_INDICATORS_IND_VALUE} - Updated value of headset indicator. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - Remote device. </li>
* </ul>
* <p>{@link #EXTRA_HF_INDICATORS_IND_ID} is defined by Bluetooth SIG and each of the indicators
* are given an assigned number. Below shows the assigned number of Indicator added so far
* are given an assigned number. Below shows the assigned number of Indicator added so far
* - Enhanced Safety - 1, Valid Values: 0 - Disabled, 1 - Enabled
* - Battery Level - 2, Valid Values: 0~100 - Remaining level of Battery
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to receive.
*
* @hide
*/
public static final String ACTION_HF_INDICATORS_VALUE_CHANGED =
@@ -278,6 +284,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
* intents that contains the assigned number of the headset indicator as defined by
* Bluetooth SIG that is being sent. Value range is 0-65535 as defined in HFP 1.7
*
* @hide
*/
public static final String EXTRA_HF_INDICATORS_IND_ID =
@@ -286,6 +293,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
* intents that contains the value of the Headset indicator that is being sent.
*
* @hide
*/
public static final String EXTRA_HF_INDICATORS_IND_VALUE =
@@ -301,27 +309,27 @@ public final class BluetoothHeadset implements BluetoothProfile {
private IBluetoothHeadset mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
if (VDBG) Log.d(TAG, "Unbinding service...");
doUnbind();
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
* Create a BluetoothHeadset proxy object.
@@ -336,7 +344,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -360,7 +368,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
mAdapter.getBluetoothManager().unbindBluetoothProfileService(
BluetoothProfile.HEADSET, mConnection);
} catch (RemoteException e) {
Log.e(TAG,"Unable to unbind HeadsetService", e);
Log.e(TAG, "Unable to unbind HeadsetService", e);
}
}
}
@@ -380,7 +388,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
mServiceListener = null;
@@ -405,14 +413,12 @@ public final class BluetoothHeadset implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.connect(device);
} catch (RemoteException e) {
@@ -446,19 +452,17 @@ public final class BluetoothHeadset implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -468,6 +472,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
if (mService != null && isEnabled()) {
@@ -485,6 +490,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
if (mService != null && isEnabled()) {
@@ -502,10 +508,10 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getConnectionState(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getConnectionState(device);
} catch (RemoteException e) {
@@ -521,7 +527,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* Set priority of the profile
*
* <p> The device should already be paired.
* Priority can be one of {@link #PRIORITY_ON} or
* Priority can be one of {@link #PRIORITY_ON} or
* {@link #PRIORITY_OFF},
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
@@ -534,11 +540,10 @@ public final class BluetoothHeadset implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON) {
return false;
if (mService != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
return mService.setPriority(device, priority);
@@ -566,8 +571,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getPriority(device);
} catch (RemoteException e) {
@@ -596,18 +600,16 @@ public final class BluetoothHeadset implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device Bluetooth headset
* @return false if there is no headset connected of if the
* connected headset doesn't support voice recognition
* or on error, true otherwise
* @return false if there is no headset connected of if the connected headset doesn't support
* voice recognition or on error, true otherwise
*/
public boolean startVoiceRecognition(BluetoothDevice device) {
if (DBG) log("startVoiceRecognition()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.startVoiceRecognition(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -621,17 +623,15 @@ public final class BluetoothHeadset implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device Bluetooth headset
* @return false if there is no headset connected
* or on error, true otherwise
* @return false if there is no headset connected or on error, true otherwise
*/
public boolean stopVoiceRecognition(BluetoothDevice device) {
if (DBG) log("stopVoiceRecognition()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.stopVoiceRecognition(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -644,17 +644,15 @@ public final class BluetoothHeadset implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device Bluetooth headset
* @return true if SCO is connected,
* false otherwise or on error
* @return true if SCO is connected, false otherwise or on error
*/
public boolean isAudioConnected(BluetoothDevice device) {
if (VDBG) log("isAudioConnected()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.isAudioConnected(device);
return mService.isAudioConnected(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -671,18 +669,16 @@ public final class BluetoothHeadset implements BluetoothProfile {
* rule of thumb, each AT command prevents the CPU from sleeping for 500 ms
*
* @param device the bluetooth headset.
* @return monotonically increasing battery usage hint, or a negative error
* code on error
* @return monotonically increasing battery usage hint, or a negative error code on error
* @hide
*/
public int getBatteryUsageHint(BluetoothDevice device) {
if (VDBG) log("getBatteryUsageHint()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getBatteryUsageHint(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -711,7 +707,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (mService != null && isEnabled()) {
try {
return mService.acceptIncomingConnect(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -721,6 +719,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* Reject the incoming connection.
*
* @hide
*/
public boolean rejectIncomingConnect(BluetoothDevice device) {
@@ -728,7 +727,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (mService != null) {
try {
return mService.rejectIncomingConnect(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -747,7 +748,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (mService != null && !isDisabled()) {
try {
return mService.getAudioState(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -763,7 +766,6 @@ public final class BluetoothHeadset implements BluetoothProfile {
* Note: This is an internal function and shouldn't be exposed
*
* @param allowed {@code true} if the profile can reroute audio, {@code false} otherwise.
*
* @hide
*/
public void setAudioRouteAllowed(boolean allowed) {
@@ -771,7 +773,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (mService != null && isEnabled()) {
try {
mService.setAudioRouteAllowed(allowed);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -789,7 +793,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (mService != null && isEnabled()) {
try {
return mService.getAudioRouteAllowed();
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -800,9 +806,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* Force SCO audio to be opened regardless any other restrictions
*
* @param forced Whether or not SCO audio connection should be forced:
* True to force SCO audio
* False to use SCO audio in normal manner
* @param forced Whether or not SCO audio connection should be forced: True to force SCO audio
* False to use SCO audio in normal manner
* @hide
*/
public void setForceScoAudio(boolean forced) {
@@ -811,7 +816,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
try {
mService.setForceScoAudio(forced);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
@@ -824,17 +829,16 @@ public final class BluetoothHeadset implements BluetoothProfile {
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @return true if SCO is connected,
* false otherwise or on error
* @return true if SCO is connected, false otherwise or on error
* @hide
*/
public boolean isAudioOn() {
if (VDBG) log("isAudioOn()");
if (mService != null && isEnabled()) {
try {
return mService.isAudioOn();
return mService.isAudioOn();
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -846,9 +850,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
* Initiates a connection of headset audio.
* It setup SCO channel with remote connected headset device.
*
* @return true if successful
* false if there was some error such as
* there is no connected headset
* @return true if successful false if there was some error such as there is no connected
* headset
* @hide
*/
public boolean connectAudio() {
@@ -869,9 +872,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
* Initiates a disconnection of headset audio.
* It tears down the SCO channel from remote headset device.
*
* @return true if successful
* false if there was some error such as
* there is no connected SCO channel
* @return true if successful false if there was some error such as there is no connected SCO
* channel
* @hide
*/
public boolean disconnectAudio() {
@@ -946,7 +948,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
int type) {
int type) {
if (mService != null && isEnabled()) {
try {
mService.phoneStateChanged(numActive, numHeld, callState, number, type);
@@ -965,7 +967,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
String number, int type) {
String number, int type) {
if (mService != null && isEnabled()) {
try {
mService.clccResponse(index, direction, status, mode, mpty, number, type);
@@ -981,9 +983,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* Sends a vendor-specific unsolicited result code to the headset.
*
* <p>The actual string to be sent is <code>command + ": " + arg</code>.
* For example, if {@code command} is {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} and {@code arg}
* is {@code "0"}, the string <code>"+ANDROID: 0"</code> will be sent.
* <p>The actual string to be sent is <code>command + ": " + arg</code>. For example, if {@code
* command} is {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} and {@code arg} is {@code "0"}, the
* string <code>"+ANDROID: 0"</code> will be sent.
*
* <p>Currently only {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} is allowed as {@code command}.
*
@@ -993,7 +995,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @param command A vendor-specific command.
* @param arg The argument that will be attached to the command.
* @return {@code false} if there is no headset connected, or if the command is not an allowed
* vendor-specific unsolicited result code, or on error. {@code true} otherwise.
* vendor-specific unsolicited result code, or on error. {@code true} otherwise.
* @throws IllegalArgumentException if {@code command} is {@code null}.
*/
public boolean sendVendorSpecificResultCode(BluetoothDevice device, String command,
@@ -1004,8 +1006,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (command == null) {
throw new IllegalArgumentException("command is null");
}
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.sendVendorSpecificResultCode(device, command, arg);
} catch (RemoteException e) {
@@ -1021,9 +1022,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* enable WBS codec setting.
*
* @return true if successful
* false if there was some error such as
* there is no connected headset
* @return true if successful false if there was some error such as there is no connected
* headset
* @hide
*/
public boolean enableWBS() {
@@ -1043,9 +1043,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* disable WBS codec settting. It set NBS codec.
*
* @return true if successful
* false if there was some error such as
* there is no connected headset
* @return true if successful false if there was some error such as there is no connected
* headset
* @hide
*/
public boolean disableWBS() {
@@ -1065,8 +1064,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* check if in-band ringing is supported for this platform.
*
* @return true if in-band ringing is supported
* false if in-band ringing is not supported
* @return true if in-band ringing is supported false if in-band ringing is not supported
* @hide
*/
public static boolean isInbandRingingSupported(Context context) {
@@ -1078,16 +1076,16 @@ public final class BluetoothHeadset implements BluetoothProfile {
* Send Headset the BIND response from AG to report change in the status of the
* HF indicators to the headset
*
* @param ind_id Assigned Number of the indicator (defined by SIG)
* @param ind_status
* possible values- false-Indicator is disabled, no value changes shall be sent for this indicator
* true-Indicator is enabled, value changes may be sent for this indicator
* @param indId Assigned Number of the indicator (defined by SIG)
* @param indStatus possible values- false-Indicator is disabled, no value changes shall be
* sent for this indicator true-Indicator is enabled, value changes may be sent for this
* indicator
* @hide
*/
public void bindResponse(int ind_id, boolean ind_status) {
public void bindResponse(int indId, boolean indStatus) {
if (mService != null && isEnabled()) {
try {
mService.bindResponse(ind_id, ind_status);
mService.bindResponse(indId, indStatus);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -1097,8 +1095,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
}
}
private final IBluetoothProfileServiceConnection mConnection
= new IBluetoothProfileServiceConnection.Stub() {
private final IBluetoothProfileServiceConnection mConnection =
new IBluetoothProfileServiceConnection.Stub() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
@@ -1106,6 +1104,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_HEADSET_SERVICE_CONNECTED));
}
@Override
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
@@ -1116,20 +1115,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
};
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
}
private boolean isDisabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_OFF) return true;
return false;
if (mAdapter.getState() == BluetoothAdapter.STATE_OFF) return true;
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
}
private static void log(String msg) {

View File

@@ -28,7 +28,6 @@ import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* Public API to control Hands Free Profile (HFP role only).
@@ -38,7 +37,7 @@ import java.util.UUID;
* <p>
*
* @hide
* */
*/
public final class BluetoothHeadsetClient implements BluetoothProfile {
private static final String TAG = "BluetoothHeadsetClient";
private static final boolean DBG = true;
@@ -71,7 +70,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* and not supported ones are <strong>not</strong> being sent at all.</p>
*/
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED";
/**
* Intent sent whenever audio state changes.
@@ -89,7 +88,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* indicating wide band speech support.</p>
*/
public static final String ACTION_AUDIO_STATE_CHANGED =
"android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED";
"android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED";
/**
* Intent sending updates of the Audio Gateway state.
@@ -146,7 +145,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Extra with information if connected audio is WBS.
* <p>Possible values: <code>true</code>,
* <code>false</code>.</p>
* <code>false</code>.</p>
*/
public static final String EXTRA_AUDIO_WBS =
"android.bluetooth.headsetclient.extra.AUDIO_WBS";
@@ -154,7 +153,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Extra for AG_EVENT indicates network status.
* <p>Value: 0 - network unavailable,
* 1 - network available </p>
* 1 - network available </p>
*/
public static final String EXTRA_NETWORK_STATUS =
"android.bluetooth.headsetclient.extra.NETWORK_STATUS";
@@ -167,7 +166,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Extra for AG_EVENT intent indicates roaming state.
* <p>Value: 0 - no roaming
* 1 - active roaming</p>
* 1 - active roaming</p>
*/
public static final String EXTRA_NETWORK_ROAMING =
"android.bluetooth.headsetclient.extra.NETWORK_ROAMING";
@@ -186,16 +185,16 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Extra for AG_EVENT intent indicates voice recognition state.
* <p>Value:
* 0 - voice recognition stopped,
* 1 - voice recognition started.</p>
* 0 - voice recognition stopped,
* 1 - voice recognition started.</p>
*/
public static final String EXTRA_VOICE_RECOGNITION =
"android.bluetooth.headsetclient.extra.VOICE_RECOGNITION";
/**
* Extra for AG_EVENT intent indicates in band ring state.
* <p>Value:
* 0 - in band ring tone not supported, or
* 1 - in band ring tone supported.</p>
* 0 - in band ring tone not supported, or
* 1 - in band ring tone supported.</p>
*/
public static final String EXTRA_IN_BAND_RING =
"android.bluetooth.headsetclient.extra.IN_BAND_RING";
@@ -208,8 +207,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
"android.bluetooth.headsetclient.extra.SUBSCRIBER_INFO";
/**
* Extra for AG_CALL_CHANGED intent indicates the
* {@link BluetoothHeadsetClientCall} object that has changed.
* Extra for AG_CALL_CHANGED intent indicates the
* {@link BluetoothHeadsetClientCall} object that has changed.
*/
public static final String EXTRA_CALL =
"android.bluetooth.headsetclient.extra.CALL";
@@ -251,53 +250,53 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* AG feature: three way calling.
*/
public final static String EXTRA_AG_FEATURE_3WAY_CALLING =
public static final String EXTRA_AG_FEATURE_3WAY_CALLING =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_3WAY_CALLING";
/**
* AG feature: voice recognition.
*/
public final static String EXTRA_AG_FEATURE_VOICE_RECOGNITION =
public static final String EXTRA_AG_FEATURE_VOICE_RECOGNITION =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_VOICE_RECOGNITION";
/**
* AG feature: fetching phone number for voice tagging procedure.
*/
public final static String EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT =
public static final String EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT";
/**
* AG feature: ability to reject incoming call.
*/
public final static String EXTRA_AG_FEATURE_REJECT_CALL =
public static final String EXTRA_AG_FEATURE_REJECT_CALL =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_REJECT_CALL";
/**
* AG feature: enhanced call handling (terminate specific call, private consultation).
*/
public final static String EXTRA_AG_FEATURE_ECC =
public static final String EXTRA_AG_FEATURE_ECC =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ECC";
/**
* AG feature: response and hold.
*/
public final static String EXTRA_AG_FEATURE_RESPONSE_AND_HOLD =
public static final String EXTRA_AG_FEATURE_RESPONSE_AND_HOLD =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RESPONSE_AND_HOLD";
/**
* AG call handling feature: accept held or waiting call in three way calling scenarios.
*/
public final static String EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL =
public static final String EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL";
/**
* AG call handling feature: release held or waiting call in three way calling scenarios.
*/
public final static String EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL =
public static final String EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL";
/**
* AG call handling feature: release active call and accept held or waiting call in three way
* calling scenarios.
*/
public final static String EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT =
public static final String EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT";
/**
* AG call handling feature: merge two calls, held and active - multi party conference mode.
*/
public final static String EXTRA_AG_FEATURE_MERGE =
public static final String EXTRA_AG_FEATURE_MERGE =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_MERGE";
/**
* AG call handling feature: merge calls and disconnect from multi party
@@ -305,61 +304,61 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* Note that this feature needs to be supported by mobile network operator
* as it requires connection and billing transfer.
*/
public final static String EXTRA_AG_FEATURE_MERGE_AND_DETACH =
public static final String EXTRA_AG_FEATURE_MERGE_AND_DETACH =
"android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_MERGE_AND_DETACH";
/* Action result codes */
public final static int ACTION_RESULT_OK = 0;
public final static int ACTION_RESULT_ERROR = 1;
public final static int ACTION_RESULT_ERROR_NO_CARRIER = 2;
public final static int ACTION_RESULT_ERROR_BUSY = 3;
public final static int ACTION_RESULT_ERROR_NO_ANSWER = 4;
public final static int ACTION_RESULT_ERROR_DELAYED = 5;
public final static int ACTION_RESULT_ERROR_BLACKLISTED = 6;
public final static int ACTION_RESULT_ERROR_CME = 7;
public static final int ACTION_RESULT_OK = 0;
public static final int ACTION_RESULT_ERROR = 1;
public static final int ACTION_RESULT_ERROR_NO_CARRIER = 2;
public static final int ACTION_RESULT_ERROR_BUSY = 3;
public static final int ACTION_RESULT_ERROR_NO_ANSWER = 4;
public static final int ACTION_RESULT_ERROR_DELAYED = 5;
public static final int ACTION_RESULT_ERROR_BLACKLISTED = 6;
public static final int ACTION_RESULT_ERROR_CME = 7;
/* Detailed CME error codes */
public final static int CME_PHONE_FAILURE = 0;
public final static int CME_NO_CONNECTION_TO_PHONE = 1;
public final static int CME_OPERATION_NOT_ALLOWED = 3;
public final static int CME_OPERATION_NOT_SUPPORTED = 4;
public final static int CME_PHSIM_PIN_REQUIRED = 5;
public final static int CME_PHFSIM_PIN_REQUIRED = 6;
public final static int CME_PHFSIM_PUK_REQUIRED = 7;
public final static int CME_SIM_NOT_INSERTED = 10;
public final static int CME_SIM_PIN_REQUIRED = 11;
public final static int CME_SIM_PUK_REQUIRED = 12;
public final static int CME_SIM_FAILURE = 13;
public final static int CME_SIM_BUSY = 14;
public final static int CME_SIM_WRONG = 15;
public final static int CME_INCORRECT_PASSWORD = 16;
public final static int CME_SIM_PIN2_REQUIRED = 17;
public final static int CME_SIM_PUK2_REQUIRED = 18;
public final static int CME_MEMORY_FULL = 20;
public final static int CME_INVALID_INDEX = 21;
public final static int CME_NOT_FOUND = 22;
public final static int CME_MEMORY_FAILURE = 23;
public final static int CME_TEXT_STRING_TOO_LONG = 24;
public final static int CME_INVALID_CHARACTER_IN_TEXT_STRING = 25;
public final static int CME_DIAL_STRING_TOO_LONG = 26;
public final static int CME_INVALID_CHARACTER_IN_DIAL_STRING = 27;
public final static int CME_NO_NETWORK_SERVICE = 30;
public final static int CME_NETWORK_TIMEOUT = 31;
public final static int CME_EMERGENCY_SERVICE_ONLY = 32;
public final static int CME_NO_SIMULTANOUS_VOIP_CS_CALLS = 33;
public final static int CME_NOT_SUPPORTED_FOR_VOIP = 34;
public final static int CME_SIP_RESPONSE_CODE = 35;
public final static int CME_NETWORK_PERSONALIZATION_PIN_REQUIRED = 40;
public final static int CME_NETWORK_PERSONALIZATION_PUK_REQUIRED = 41;
public final static int CME_NETWORK_SUBSET_PERSONALIZATION_PIN_REQUIRED = 42;
public final static int CME_NETWORK_SUBSET_PERSONALIZATION_PUK_REQUIRED = 43;
public final static int CME_SERVICE_PROVIDER_PERSONALIZATION_PIN_REQUIRED = 44;
public final static int CME_SERVICE_PROVIDER_PERSONALIZATION_PUK_REQUIRED = 45;
public final static int CME_CORPORATE_PERSONALIZATION_PIN_REQUIRED = 46;
public final static int CME_CORPORATE_PERSONALIZATION_PUK_REQUIRED = 47;
public final static int CME_HIDDEN_KEY_REQUIRED = 48;
public final static int CME_EAP_NOT_SUPPORTED = 49;
public final static int CME_INCORRECT_PARAMETERS = 50;
public static final int CME_PHONE_FAILURE = 0;
public static final int CME_NO_CONNECTION_TO_PHONE = 1;
public static final int CME_OPERATION_NOT_ALLOWED = 3;
public static final int CME_OPERATION_NOT_SUPPORTED = 4;
public static final int CME_PHSIM_PIN_REQUIRED = 5;
public static final int CME_PHFSIM_PIN_REQUIRED = 6;
public static final int CME_PHFSIM_PUK_REQUIRED = 7;
public static final int CME_SIM_NOT_INSERTED = 10;
public static final int CME_SIM_PIN_REQUIRED = 11;
public static final int CME_SIM_PUK_REQUIRED = 12;
public static final int CME_SIM_FAILURE = 13;
public static final int CME_SIM_BUSY = 14;
public static final int CME_SIM_WRONG = 15;
public static final int CME_INCORRECT_PASSWORD = 16;
public static final int CME_SIM_PIN2_REQUIRED = 17;
public static final int CME_SIM_PUK2_REQUIRED = 18;
public static final int CME_MEMORY_FULL = 20;
public static final int CME_INVALID_INDEX = 21;
public static final int CME_NOT_FOUND = 22;
public static final int CME_MEMORY_FAILURE = 23;
public static final int CME_TEXT_STRING_TOO_LONG = 24;
public static final int CME_INVALID_CHARACTER_IN_TEXT_STRING = 25;
public static final int CME_DIAL_STRING_TOO_LONG = 26;
public static final int CME_INVALID_CHARACTER_IN_DIAL_STRING = 27;
public static final int CME_NO_NETWORK_SERVICE = 30;
public static final int CME_NETWORK_TIMEOUT = 31;
public static final int CME_EMERGENCY_SERVICE_ONLY = 32;
public static final int CME_NO_SIMULTANOUS_VOIP_CS_CALLS = 33;
public static final int CME_NOT_SUPPORTED_FOR_VOIP = 34;
public static final int CME_SIP_RESPONSE_CODE = 35;
public static final int CME_NETWORK_PERSONALIZATION_PIN_REQUIRED = 40;
public static final int CME_NETWORK_PERSONALIZATION_PUK_REQUIRED = 41;
public static final int CME_NETWORK_SUBSET_PERSONALIZATION_PIN_REQUIRED = 42;
public static final int CME_NETWORK_SUBSET_PERSONALIZATION_PUK_REQUIRED = 43;
public static final int CME_SERVICE_PROVIDER_PERSONALIZATION_PIN_REQUIRED = 44;
public static final int CME_SERVICE_PROVIDER_PERSONALIZATION_PUK_REQUIRED = 45;
public static final int CME_CORPORATE_PERSONALIZATION_PIN_REQUIRED = 46;
public static final int CME_CORPORATE_PERSONALIZATION_PUK_REQUIRED = 47;
public static final int CME_HIDDEN_KEY_REQUIRED = 48;
public static final int CME_EAP_NOT_SUPPORTED = 49;
public static final int CME_INCORRECT_PARAMETERS = 50;
/* Action policy for other calls when accepting call */
public static final int CALL_ACCEPT_NONE = 0;
@@ -371,36 +370,37 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
private IBluetoothHeadsetClient mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
@Override
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
Intent intent = new Intent(IBluetoothHeadsetClient.class.getName());
if (VDBG) Log.d(TAG, "Binding service...");
Intent intent = new Intent(
IBluetoothHeadsetClient.class.getName());
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
* Create a BluetoothHeadsetClient proxy object.
@@ -415,7 +415,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -427,7 +427,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
intent.setComponent(comp);
if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
android.os.Process.myUserHandle())) {
android.os.Process.myUserHandle())) {
Log.e(TAG, "Could not bind to Bluetooth Headset Client Service with " + intent);
return false;
}
@@ -448,7 +448,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -458,7 +458,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
@@ -472,16 +472,13 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* second connection, this implementation will disconnect already connected
* device automatically and will process the new one.
*
* @param device a remote device we want connect to
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED}
* intent.
* @param device a remote device we want connect to
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.connect(device);
} catch (RemoteException e) {
@@ -496,21 +493,18 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Disconnects remote device
*
* @param device a remote device we want disconnect
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED}
* intent.
* @param device a remote device we want disconnect
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -540,10 +534,9 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Returns list of remote devices in a particular state
*
* @param states collection of states
* @return list of devices that state matches the states listed in
* <code>states</code>; empty list if nothing matches the
* <code>states</code>
* @param states collection of states
* @return list of devices that state matches the states listed in <code>states</code>; empty
* list if nothing matches the <code>states</code>
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
@@ -563,14 +556,13 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Returns state of the <code>device</code>
*
* @param device a remote device
* @return the state of connection of the device
* @param device a remote device
* @return the state of connection of the device
*/
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getConnectionState(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getConnectionState(device);
} catch (RemoteException e) {
@@ -589,11 +581,10 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON) {
return false;
if (mService != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
return mService.setPriority(device, priority);
@@ -611,8 +602,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getPriority(device);
} catch (RemoteException e) {
@@ -627,24 +617,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Starts voice recognition.
*
* @param device remote device
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_AG_EVENT}
* intent.
* @param device remote device
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_AG_EVENT} intent.
*
* <p>Feature required for successful execution is being reported by:
* {@link #EXTRA_AG_FEATURE_VOICE_RECOGNITION}.
* This method invocation will fail silently when feature is not supported.</p>
* <p>Feature required for successful execution is being reported by: {@link
* #EXTRA_AG_FEATURE_VOICE_RECOGNITION}. This method invocation will fail silently when feature
* is not supported.</p>
*/
public boolean startVoiceRecognition(BluetoothDevice device) {
if (DBG) log("startVoiceRecognition()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.startVoiceRecognition(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -654,24 +641,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Stops voice recognition.
*
* @param device remote device
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_AG_EVENT}
* intent.
* @param device remote device
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_AG_EVENT} intent.
*
* <p>Feature required for successful execution is being reported by:
* {@link #EXTRA_AG_FEATURE_VOICE_RECOGNITION}.
* This method invocation will fail silently when feature is not supported.</p>
* <p>Feature required for successful execution is being reported by: {@link
* #EXTRA_AG_FEATURE_VOICE_RECOGNITION}. This method invocation will fail silently when feature
* is not supported.</p>
*/
public boolean stopVoiceRecognition(BluetoothDevice device) {
if (DBG) log("stopVoiceRecognition()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.stopVoiceRecognition(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -681,17 +665,16 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Returns list of all calls in any state.
*
* @param device remote device
* @return list of calls; empty list if none call exists
* @param device remote device
* @return list of calls; empty list if none call exists
*/
public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
if (DBG) log("getCurrentCalls()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getCurrentCalls(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -701,18 +684,16 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Returns list of current values of AG indicators.
*
* @param device remote device
* @return bundle of AG indicators; null if device is not in
* CONNECTED state
* @param device remote device
* @return bundle of AG indicators; null if device is not in CONNECTED state
*/
public Bundle getCurrentAgEvents(BluetoothDevice device) {
if (DBG) log("getCurrentCalls()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getCurrentAgEvents(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -722,23 +703,19 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Accepts a call
*
* @param device remote device
* @param flag action policy while accepting a call. Possible values
* {@link #CALL_ACCEPT_NONE}, {@link #CALL_ACCEPT_HOLD},
* {@link #CALL_ACCEPT_TERMINATE}
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_CALL_CHANGED}
* intent.
* @param device remote device
* @param flag action policy while accepting a call. Possible values {@link #CALL_ACCEPT_NONE},
* {@link #CALL_ACCEPT_HOLD}, {@link #CALL_ACCEPT_TERMINATE}
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*/
public boolean acceptCall(BluetoothDevice device, int flag) {
if (DBG) log("acceptCall()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.acceptCall(device, flag);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -748,20 +725,17 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Holds a call.
*
* @param device remote device
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_CALL_CHANGED}
* intent.
* @param device remote device
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*/
public boolean holdCall(BluetoothDevice device) {
if (DBG) log("holdCall()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.holdCall(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -771,24 +745,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Rejects a call.
*
* @param device remote device
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_CALL_CHANGED}
* intent.
* @param device remote device
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*
* <p>Feature required for successful execution is being reported by:
* {@link #EXTRA_AG_FEATURE_REJECT_CALL}.
* This method invocation will fail silently when feature is not supported.</p>
* <p>Feature required for successful execution is being reported by: {@link
* #EXTRA_AG_FEATURE_REJECT_CALL}. This method invocation will fail silently when feature is not
* supported.</p>
*/
public boolean rejectCall(BluetoothDevice device) {
if (DBG) log("rejectCall()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.rejectCall(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -800,27 +771,24 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*
* Works only when Extended Call Control is supported by Audio Gateway.
*
* @param device remote device
* @param call Handle of call obtained in {@link dial()} or obtained via
* {@link ACTION_CALL_CHANGED}. {@code call} may be null in which
* case we will hangup all active calls.
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_CALL_CHANGED}
* intent.
* @param device remote device
* @param call Handle of call obtained in {@link #dial(BluetoothDevice, String)} or obtained via
* {@link #ACTION_CALL_CHANGED}. {@code call} may be null in which case we will hangup all active
* calls.
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*
* <p>Feature required for successful execution is being reported by:
* {@link #EXTRA_AG_FEATURE_ECC}.
* This method invocation will fail silently when feature is not supported.</p>
* <p>Feature required for successful execution is being reported by: {@link
* #EXTRA_AG_FEATURE_ECC}. This method invocation will fail silently when feature is not
* supported.</p>
*/
public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
if (DBG) log("terminateCall()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.terminateCall(device, call);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -832,25 +800,22 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*
* Works only when Extended Call Control is supported by Audio Gateway.
*
* @param device remote device
* @param index index of the call to connect in private mode
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_CALL_CHANGED}
* intent.
* @param device remote device
* @param index index of the call to connect in private mode
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*
* <p>Feature required for successful execution is being reported by:
* {@link #EXTRA_AG_FEATURE_ECC}.
* This method invocation will fail silently when feature is not supported.</p>
* <p>Feature required for successful execution is being reported by: {@link
* #EXTRA_AG_FEATURE_ECC}. This method invocation will fail silently when feature is not
* supported.</p>
*/
public boolean enterPrivateMode(BluetoothDevice device, int index) {
if (DBG) log("enterPrivateMode()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.enterPrivateMode(device, index);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -862,24 +827,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*
* That means connect other calls and disconnect.
*
* @param device remote device
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_CALL_CHANGED}
* intent.
* @param device remote device
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*
* <p>Feature required for successful execution is being reported by:
* {@link #EXTRA_AG_FEATURE_MERGE_AND_DETACH}.
* This method invocation will fail silently when feature is not supported.</p>
* <p>Feature required for successful execution is being reported by: {@link
* #EXTRA_AG_FEATURE_MERGE_AND_DETACH}. This method invocation will fail silently when feature
* is not supported.</p>
*/
public boolean explicitCallTransfer(BluetoothDevice device) {
if (DBG) log("explicitCallTransfer()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.explicitCallTransfer(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -889,23 +851,19 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Places a call with specified number.
*
* @param device remote device
* @param number valid phone number
* @return <code>{@link BluetoothHeadsetClientCall} call</code> if command has been
* issued successfully;
* <code>{@link null}</code> otherwise;
* upon completion HFP sends {@link #ACTION_CALL_CHANGED}
* intent in case of success; {@link #ACTION_RESULT} is sent
* otherwise;
* @param device remote device
* @param number valid phone number
* @return <code>{@link BluetoothHeadsetClientCall} call</code> if command has been issued
* successfully; <code>{@link null}</code> otherwise; upon completion HFP sends {@link
* #ACTION_CALL_CHANGED} intent in case of success; {@link #ACTION_RESULT} is sent otherwise;
*/
public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
if (DBG) log("dial()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.dial(device, number);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -917,20 +875,18 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*
* Possible code values : 0,1,2,3,4,5,6,7,8,9,A,B,C,D,*,#
*
* @param device remote device
* @param code ASCII code
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_RESULT} intent;
* @param device remote device
* @param code ASCII code
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_RESULT} intent;
*/
public boolean sendDTMF(BluetoothDevice device, byte code) {
if (DBG) log("sendDTMF()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.sendDTMF(device, code);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -940,24 +896,22 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Get a number corresponding to last voice tag recorded on AG.
*
* @param device remote device
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_LAST_VTAG}
* or {@link #ACTION_RESULT} intent;
* @param device remote device
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_LAST_VTAG} or {@link #ACTION_RESULT}
* intent;
*
* <p>Feature required for successful execution is being reported by:
* {@link #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT}.
* This method invocation will fail silently when feature is not supported.</p>
* <p>Feature required for successful execution is being reported by: {@link
* #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT}. This method invocation will fail silently when
* feature is not supported.</p>
*/
public boolean getLastVoiceTagNumber(BluetoothDevice device) {
if (DBG) log("getLastVoiceTagNumber()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getLastVoiceTagNumber(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -974,7 +928,9 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
if (mService != null && isEnabled()) {
try {
return mService.getAudioState(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -985,16 +941,18 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Sets whether audio routing is allowed.
*
* @param device remote device
* @param allowed if routing is allowed to the device
* Note: This is an internal function and shouldn't be exposed
* @param device remote device
* @param allowed if routing is allowed to the device Note: This is an internal function and
* shouldn't be exposed
*/
public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
if (VDBG) log("setAudioRouteAllowed");
if (mService != null && isEnabled()) {
try {
mService.setAudioRouteAllowed(device, allowed);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -1003,16 +961,19 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Returns whether audio routing is allowed.
* @param device remote device
* @return whether the command succeeded
* Note: This is an internal function and shouldn't be exposed
*
* @param device remote device
* @return whether the command succeeded Note: This is an internal function and shouldn't be
* exposed
*/
public boolean getAudioRouteAllowed(BluetoothDevice device) {
if (VDBG) log("getAudioRouteAllowed");
if (mService != null && isEnabled()) {
try {
return mService.getAudioRouteAllowed(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -1025,11 +986,9 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*
* It setup SCO channel with remote connected Handsfree AG device.
*
* @param device remote device
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED}
* intent;
* @param device remote device
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
*/
public boolean connectAudio(BluetoothDevice device) {
if (mService != null && isEnabled()) {
@@ -1050,11 +1009,9 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*
* It tears down the SCO channel from remote AG device.
*
* @param device remote device
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED}
* intent;
* @param device remote device
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
*/
public boolean disconnectAudio(BluetoothDevice device) {
if (mService != null && isEnabled()) {
@@ -1073,9 +1030,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
/**
* Get Audio Gateway features
*
* @param device remote device
* @return bundle of AG features; null if no service or
* AG not connected
* @param device remote device
* @return bundle of AG features; null if no service or AG not connected
*/
public Bundle getCurrentAgFeatures(BluetoothDevice device) {
if (mService != null && isEnabled()) {
@@ -1103,6 +1059,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
BluetoothHeadsetClient.this);
}
}
@Override
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
@@ -1114,15 +1071,15 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
};
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
}
private static void log(String msg) {

View File

@@ -25,6 +25,7 @@ import java.util.UUID;
/**
* This class represents a single call, its state and properties.
* It implements {@link Parcelable} for inter-process message passing.
*
* @hide
*/
public final class BluetoothHeadsetClientCall implements Parcelable {
@@ -98,7 +99,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
*
* <p>Note: This is an internal function and shouldn't be exposed</p>
*
* @param state new call state.
* @param state new call state.
*/
public void setState(int state) {
mState = state;
@@ -109,7 +110,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
*
* <p>Note: This is an internal function and shouldn't be exposed</p>
*
* @param number String representing phone number.
* @param number String representing phone number.
*/
public void setNumber(String number) {
mNumber = number;
@@ -120,8 +121,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
*
* <p>Note: This is an internal function and shouldn't be exposed</p>
*
* @param multiParty if <code>true</code> sets this call as a part
* of multi party conference.
* @param multiParty if <code>true</code> sets this call as a part of multi party conference.
*/
public void setMultiParty(boolean multiParty) {
mMultiParty = multiParty;
@@ -185,8 +185,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
/**
* Checks if call is an active call in a conference mode (aka multi party).
*
* @return <code>true</code> if call is a multi party call,
* <code>false</code> otherwise.
* @return <code>true</code> if call is a multi party call, <code>false</code> otherwise.
*/
public boolean isMultiParty() {
return mMultiParty;
@@ -195,17 +194,22 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
/**
* Checks if this call is an outgoing call.
*
* @return <code>true</code> if its outgoing call,
* <code>false</code> otherwise.
* @return <code>true</code> if its outgoing call, <code>false</code> otherwise.
*/
public boolean isOutgoing() {
return mOutgoing;
}
@Override
public String toString() {
return toString(false);
}
/**
* Generate a log string for this call
* @param loggable whether device address should be logged
* @return log string
*/
public String toString(boolean loggable) {
StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mDevice: ");
builder.append(loggable ? mDevice : mDevice.hashCode());
@@ -215,15 +219,33 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
builder.append(mUUID);
builder.append(", mState: ");
switch (mState) {
case CALL_STATE_ACTIVE: builder.append("ACTIVE"); break;
case CALL_STATE_HELD: builder.append("HELD"); break;
case CALL_STATE_DIALING: builder.append("DIALING"); break;
case CALL_STATE_ALERTING: builder.append("ALERTING"); break;
case CALL_STATE_INCOMING: builder.append("INCOMING"); break;
case CALL_STATE_WAITING: builder.append("WAITING"); break;
case CALL_STATE_HELD_BY_RESPONSE_AND_HOLD: builder.append("HELD_BY_RESPONSE_AND_HOLD"); break;
case CALL_STATE_TERMINATED: builder.append("TERMINATED"); break;
default: builder.append(mState); break;
case CALL_STATE_ACTIVE:
builder.append("ACTIVE");
break;
case CALL_STATE_HELD:
builder.append("HELD");
break;
case CALL_STATE_DIALING:
builder.append("DIALING");
break;
case CALL_STATE_ALERTING:
builder.append("ALERTING");
break;
case CALL_STATE_INCOMING:
builder.append("INCOMING");
break;
case CALL_STATE_WAITING:
builder.append("WAITING");
break;
case CALL_STATE_HELD_BY_RESPONSE_AND_HOLD:
builder.append("HELD_BY_RESPONSE_AND_HOLD");
break;
case CALL_STATE_TERMINATED:
builder.append("TERMINATED");
break;
default:
builder.append(mState);
break;
}
builder.append(", mNumber: ");
builder.append(loggable ? mNumber : mNumber.hashCode());
@@ -242,7 +264,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
new Parcelable.Creator<BluetoothHeadsetClientCall>() {
@Override
public BluetoothHeadsetClientCall createFromParcel(Parcel in) {
return new BluetoothHeadsetClientCall((BluetoothDevice)in.readParcelable(null),
return new BluetoothHeadsetClientCall((BluetoothDevice) in.readParcelable(null),
in.readInt(), UUID.fromString(in.readString()), in.readInt(),
in.readString(), in.readInt() == 1, in.readInt() == 1);
}

View File

@@ -36,24 +36,23 @@ import java.util.List;
* Service via IPC.
*
* <p> How to connect to a health device which is acting in the source role.
* <li> Use {@link BluetoothAdapter#getProfileProxy} to get
* the BluetoothHealth proxy object. </li>
* <li> Create an {@link BluetoothHealth} callback and call
* {@link #registerSinkAppConfiguration} to register an application
* configuration </li>
* <li> Pair with the remote device. This currently needs to be done manually
* from Bluetooth Settings </li>
* <li> Connect to a health device using {@link #connectChannelToSource}. Some
* devices will connect the channel automatically. The {@link BluetoothHealth}
* callback will inform the application of channel state change. </li>
* <li> Use the file descriptor provided with a connected channel to read and
* write data to the health channel. </li>
* <li> The received data needs to be interpreted using a health manager which
* implements the IEEE 11073-xxxxx specifications.
* <li> When done, close the health channel by calling {@link #disconnectChannel}
* and unregister the application configuration calling
* {@link #unregisterAppConfiguration}
*
* <li> Use {@link BluetoothAdapter#getProfileProxy} to get
* the BluetoothHealth proxy object. </li>
* <li> Create an {@link BluetoothHealth} callback and call
* {@link #registerSinkAppConfiguration} to register an application
* configuration </li>
* <li> Pair with the remote device. This currently needs to be done manually
* from Bluetooth Settings </li>
* <li> Connect to a health device using {@link #connectChannelToSource}. Some
* devices will connect the channel automatically. The {@link BluetoothHealth}
* callback will inform the application of channel state change. </li>
* <li> Use the file descriptor provided with a connected channel to read and
* write data to the health channel. </li>
* <li> The received data needs to be interpreted using a health manager which
* implements the IEEE 11073-xxxxx specifications.
* <li> When done, close the health channel by calling {@link #disconnectChannel}
* and unregister the application configuration calling
* {@link #unregisterAppConfiguration}
*/
public final class BluetoothHealth implements BluetoothProfile {
private static final String TAG = "BluetoothHealth";
@@ -98,34 +97,34 @@ public final class BluetoothHealth implements BluetoothProfile {
/** @hide */
public static final int HEALTH_OPERATION_NOT_ALLOWED = 6005;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
@@ -137,10 +136,10 @@ public final class BluetoothHealth implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param name The friendly name associated with the application or configuration.
* @param dataType The dataType of the Source role of Health Profile to which
* the sink wants to connect to.
* @param callback A callback to indicate success or failure of the registration and
* all operations done on this application configuration.
* @param dataType The dataType of the Source role of Health Profile to which the sink wants to
* connect to.
* @param callback A callback to indicate success or failure of the registration and all
* operations done on this application configuration.
* @return If true, callback will be called.
*/
public boolean registerSinkAppConfiguration(String name, int dataType,
@@ -161,9 +160,8 @@ public final class BluetoothHealth implements BluetoothProfile {
*
* @param name The friendly name associated with the application or configuration.
* @param dataType The dataType of the Source role of Health Profile.
* @param channelType The channel type. Will be one of
* {@link #CHANNEL_TYPE_RELIABLE} or
* {@link #CHANNEL_TYPE_STREAMING}
* @param channelType The channel type. Will be one of {@link #CHANNEL_TYPE_RELIABLE} or {@link
* #CHANNEL_TYPE_STREAMING}
* @param callback - A callback to indicate success or failure.
* @return If true, callback will be called.
* @hide
@@ -197,7 +195,7 @@ public final class BluetoothHealth implements BluetoothProfile {
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param config The health app configuration
* @param config The health app configuration
* @return Success or failure.
*/
public boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) {
@@ -224,14 +222,13 @@ public final class BluetoothHealth implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device The remote Bluetooth device.
* @param config The application configuration which has been registered using
* {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
* @param config The application configuration which has been registered using {@link
* #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
* @return If true, the callback associated with the application config will be called.
*/
public boolean connectChannelToSource(BluetoothDevice device,
BluetoothHealthAppConfiguration config) {
if (mService != null && isEnabled() && isValidDevice(device) &&
config != null) {
if (mService != null && isEnabled() && isValidDevice(device) && config != null) {
try {
return mService.connectChannelToSource(device, config);
} catch (RemoteException e) {
@@ -249,18 +246,17 @@ public final class BluetoothHealth implements BluetoothProfile {
* This is an asynchronous call. If this function returns true, the callback
* associated with the application configuration will be called.
*
*<p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device The remote Bluetooth device.
* @param config The application configuration which has been registered using
* {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
* @param config The application configuration which has been registered using {@link
* #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
* @return If true, the callback associated with the application config will be called.
* @hide
*/
public boolean connectChannelToSink(BluetoothDevice device,
BluetoothHealthAppConfiguration config, int channelType) {
if (mService != null && isEnabled() && isValidDevice(device) &&
config != null) {
if (mService != null && isEnabled() && isValidDevice(device) && config != null) {
try {
return mService.connectChannelToSink(device, config, channelType);
} catch (RemoteException e) {
@@ -278,18 +274,17 @@ public final class BluetoothHealth implements BluetoothProfile {
* This is an asynchronous call. If this function returns true, the callback
* associated with the application configuration will be called.
*
*<p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param device The remote Bluetooth device.
* @param config The application configuration which has been registered using
* {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
* @param config The application configuration which has been registered using {@link
* #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
* @param channelId The channel id associated with the channel
* @return If true, the callback associated with the application config will be called.
*/
public boolean disconnectChannel(BluetoothDevice device,
BluetoothHealthAppConfiguration config, int channelId) {
if (mService != null && isEnabled() && isValidDevice(device) &&
config != null) {
if (mService != null && isEnabled() && isValidDevice(device) && config != null) {
try {
return mService.disconnectChannel(device, config, channelId);
} catch (RemoteException e) {
@@ -317,8 +312,7 @@ public final class BluetoothHealth implements BluetoothProfile {
*/
public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
BluetoothHealthAppConfiguration config) {
if (mService != null && isEnabled() && isValidDevice(device) &&
config != null) {
if (mService != null && isEnabled() && isValidDevice(device) && config != null) {
try {
return mService.getMainChannelFd(device, config);
} catch (RemoteException e) {
@@ -342,9 +336,8 @@ public final class BluetoothHealth implements BluetoothProfile {
* local adapter.
*
* @param device Remote bluetooth device.
* @return State of the profile connection. One of
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
* @return State of the profile connection. One of {@link #STATE_CONNECTED}, {@link
* #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
@@ -372,6 +365,7 @@ public final class BluetoothHealth implements BluetoothProfile {
* state of the local Bluetooth adapter for this profile. This can be used
* by applications like status bar which would just like to know the state of the
* local adapter.
*
* @return List of devices. The list will be empty on error.
*/
@Override
@@ -401,9 +395,8 @@ public final class BluetoothHealth implements BluetoothProfile {
* by applications like status bar which would just like to know the state of the
* local adapter.
*
* @param states Array of states. States can be one of
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
* @param states Array of states. States can be one of {@link #STATE_CONNECTED}, {@link
* #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
* @return List of devices. The list will be empty on error.
*/
@Override
@@ -429,25 +422,25 @@ public final class BluetoothHealth implements BluetoothProfile {
@Override
public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
int status) {
mCallback.onHealthAppConfigurationStatusChange(config, status);
int status) {
mCallback.onHealthAppConfigurationStatusChange(config, status);
}
@Override
public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
BluetoothDevice device, int prevState, int newState,
ParcelFileDescriptor fd, int channelId) {
BluetoothDevice device, int prevState, int newState,
ParcelFileDescriptor fd, int channelId) {
mCallback.onHealthChannelStateChange(config, device, prevState, newState, fd,
channelId);
channelId);
}
}
/** Health Channel Connection State - Disconnected */
public static final int STATE_CHANNEL_DISCONNECTED = 0;
/** Health Channel Connection State - Disconnected */
public static final int STATE_CHANNEL_DISCONNECTED = 0;
/** Health Channel Connection State - Connecting */
public static final int STATE_CHANNEL_CONNECTING = 1;
public static final int STATE_CHANNEL_CONNECTING = 1;
/** Health Channel Connection State - Connected */
public static final int STATE_CHANNEL_CONNECTED = 2;
public static final int STATE_CHANNEL_CONNECTED = 2;
/** Health Channel Connection State - Disconnecting */
public static final int STATE_CHANNEL_DISCONNECTING = 3;
@@ -477,7 +470,7 @@ public final class BluetoothHealth implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -503,7 +496,7 @@ public final class BluetoothHealth implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -513,7 +506,7 @@ public final class BluetoothHealth implements BluetoothProfile {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
@@ -529,6 +522,7 @@ public final class BluetoothHealth implements BluetoothProfile {
mServiceListener.onServiceConnected(BluetoothProfile.HEALTH, BluetoothHealth.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
@@ -555,10 +549,10 @@ public final class BluetoothHealth implements BluetoothProfile {
private boolean checkAppParam(String name, int role, int channelType,
BluetoothHealthCallback callback) {
if (name == null || (role != SOURCE_ROLE && role != SINK_ROLE) ||
(channelType != CHANNEL_TYPE_RELIABLE &&
channelType != CHANNEL_TYPE_STREAMING &&
channelType != CHANNEL_TYPE_ANY) || callback == null) {
if (name == null || (role != SOURCE_ROLE && role != SINK_ROLE)
|| (channelType != CHANNEL_TYPE_RELIABLE && channelType != CHANNEL_TYPE_STREAMING
&& channelType != CHANNEL_TYPE_ANY)
|| callback == null) {
return false;
}
if (role == SOURCE_ROLE && channelType == CHANNEL_TYPE_ANY) return false;

View File

@@ -25,7 +25,6 @@ import android.os.Parcelable;
* the {@link BluetoothHealth} class. This class represents an application configuration
* that the Bluetooth Health third party application will register to communicate with the
* remote Bluetooth health device.
*
*/
public final class BluetoothHealthAppConfiguration implements Parcelable {
private final String mName;
@@ -52,12 +51,11 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
*
* @param name Friendly name associated with the application configuration
* @param dataType Data Type of the remote Bluetooth Health device
* @param role {@link BluetoothHealth#SOURCE_ROLE} or
* {@link BluetoothHealth#SINK_ROLE}
* @param role {@link BluetoothHealth#SOURCE_ROLE} or {@link BluetoothHealth#SINK_ROLE}
* @hide
*/
BluetoothHealthAppConfiguration(String name, int dataType, int role, int
channelType) {
channelType) {
mName = name;
mDataType = dataType;
mRole = role;
@@ -71,10 +69,8 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
if (mName == null) return false;
return mName.equals(config.getName()) &&
mDataType == config.getDataType() &&
mRole == config.getRole() &&
mChannelType == config.getChannelType();
return mName.equals(config.getName()) && mDataType == config.getDataType()
&& mRole == config.getRole() && mChannelType == config.getChannelType();
}
return false;
}
@@ -91,11 +87,11 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
@Override
public String toString() {
return "BluetoothHealthAppConfiguration [mName = " + mName +
",mDataType = " + mDataType + ", mRole = " + mRole + ",mChannelType = " +
mChannelType + "]";
return "BluetoothHealthAppConfiguration [mName = " + mName + ",mDataType = " + mDataType
+ ", mRole = " + mRole + ",mChannelType = " + mChannelType + "]";
}
@Override
public int describeContents() {
return 0;
}
@@ -121,8 +117,7 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
/**
* Return the role associated with this application configuration.
*
* @return One of {@link BluetoothHealth#SOURCE_ROLE} or
* {@link BluetoothHealth#SINK_ROLE}
* @return One of {@link BluetoothHealth#SOURCE_ROLE} or {@link BluetoothHealth#SINK_ROLE}
*/
public int getRole() {
return mRole;
@@ -131,9 +126,8 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
/**
* Return the channel type associated with this application configuration.
*
* @return One of {@link BluetoothHealth#CHANNEL_TYPE_RELIABLE} or
* {@link BluetoothHealth#CHANNEL_TYPE_STREAMING} or
* {@link BluetoothHealth#CHANNEL_TYPE_ANY}.
* @return One of {@link BluetoothHealth#CHANNEL_TYPE_RELIABLE} or {@link
* BluetoothHealth#CHANNEL_TYPE_STREAMING} or {@link BluetoothHealth#CHANNEL_TYPE_ANY}.
* @hide
*/
public int getChannelType() {
@@ -141,23 +135,24 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
}
public static final Parcelable.Creator<BluetoothHealthAppConfiguration> CREATOR =
new Parcelable.Creator<BluetoothHealthAppConfiguration>() {
@Override
public BluetoothHealthAppConfiguration createFromParcel(Parcel in) {
String name = in.readString();
int type = in.readInt();
int role = in.readInt();
int channelType = in.readInt();
return new BluetoothHealthAppConfiguration(name, type, role,
channelType);
}
new Parcelable.Creator<BluetoothHealthAppConfiguration>() {
@Override
public BluetoothHealthAppConfiguration createFromParcel(Parcel in) {
String name = in.readString();
int type = in.readInt();
int role = in.readInt();
int channelType = in.readInt();
return new BluetoothHealthAppConfiguration(name, type, role,
channelType);
}
@Override
public BluetoothHealthAppConfiguration[] newArray(int size) {
return new BluetoothHealthAppConfiguration[size];
}
};
@Override
public BluetoothHealthAppConfiguration[] newArray(int size) {
return new BluetoothHealthAppConfiguration[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(mName);
out.writeInt(mDataType);

View File

@@ -33,12 +33,11 @@ public abstract class BluetoothHealthCallback {
* <p> This callback is called on the binder thread (not on the UI thread)
*
* @param config Bluetooth Health app configuration
* @param status Success or failure of the registration or unregistration
* calls. Can be one of
* {@link BluetoothHealth#APP_CONFIG_REGISTRATION_SUCCESS} or
* {@link BluetoothHealth#APP_CONFIG_REGISTRATION_FAILURE} or
* {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_SUCCESS} or
* {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_FAILURE}
* @param status Success or failure of the registration or unregistration calls. Can be one of
* {@link BluetoothHealth#APP_CONFIG_REGISTRATION_SUCCESS} or {@link
* BluetoothHealth#APP_CONFIG_REGISTRATION_FAILURE} or
* {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_SUCCESS}
* or {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_FAILURE}
*/
@BinderThread
public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
@@ -57,15 +56,15 @@ public abstract class BluetoothHealthCallback {
* @param prevState The previous state of the channel
* @param newState The new state of the channel.
* @param fd The Parcel File Descriptor when the channel state is connected.
* @param channelId The id associated with the channel. This id will be used
* in future calls like when disconnecting the channel.
* @param channelId The id associated with the channel. This id will be used in future calls
* like when disconnecting the channel.
*/
@BinderThread
public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
BluetoothDevice device, int prevState, int newState, ParcelFileDescriptor fd,
int channelId) {
Log.d(TAG, "onHealthChannelStateChange: " + config + "Device: " + device +
"prevState:" + prevState + "newState:" + newState + "ParcelFd:" + fd +
"ChannelId:" + channelId);
Log.d(TAG, "onHealthChannelStateChange: " + config + "Device: " + device
+ "prevState:" + prevState + "newState:" + newState + "ParcelFd:" + fd
+ "ChannelId:" + channelId);
}
}

View File

@@ -49,19 +49,19 @@ public final class BluetoothHidDeviceAppConfiguration implements Parcelable {
}
public static final Parcelable.Creator<BluetoothHidDeviceAppConfiguration> CREATOR =
new Parcelable.Creator<BluetoothHidDeviceAppConfiguration>() {
new Parcelable.Creator<BluetoothHidDeviceAppConfiguration>() {
@Override
public BluetoothHidDeviceAppConfiguration createFromParcel(Parcel in) {
long hash = in.readLong();
return new BluetoothHidDeviceAppConfiguration(hash);
}
@Override
public BluetoothHidDeviceAppConfiguration createFromParcel(Parcel in) {
long hash = in.readLong();
return new BluetoothHidDeviceAppConfiguration(hash);
}
@Override
public BluetoothHidDeviceAppConfiguration[] newArray(int size) {
return new BluetoothHidDeviceAppConfiguration[size];
}
};
@Override
public BluetoothHidDeviceAppConfiguration[] newArray(int size) {
return new BluetoothHidDeviceAppConfiguration[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {

View File

@@ -19,23 +19,21 @@ package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Random;
/** @hide */
public final class BluetoothHidDeviceAppQosSettings implements Parcelable {
final public int serviceType;
final public int tokenRate;
final public int tokenBucketSize;
final public int peakBandwidth;
final public int latency;
final public int delayVariation;
public final int serviceType;
public final int tokenRate;
public final int tokenBucketSize;
public final int peakBandwidth;
public final int latency;
public final int delayVariation;
final static public int SERVICE_NO_TRAFFIC = 0x00;
final static public int SERVICE_BEST_EFFORT = 0x01;
final static public int SERVICE_GUARANTEED = 0x02;
public static final int SERVICE_NO_TRAFFIC = 0x00;
public static final int SERVICE_BEST_EFFORT = 0x01;
public static final int SERVICE_GUARANTEED = 0x02;
final static public int MAX = (int) 0xffffffff;
public static final int MAX = (int) 0xffffffff;
public BluetoothHidDeviceAppQosSettings(int serviceType, int tokenRate, int tokenBucketSize,
int peakBandwidth,
@@ -63,21 +61,22 @@ public final class BluetoothHidDeviceAppQosSettings implements Parcelable {
}
public static final Parcelable.Creator<BluetoothHidDeviceAppQosSettings> CREATOR =
new Parcelable.Creator<BluetoothHidDeviceAppQosSettings>() {
new Parcelable.Creator<BluetoothHidDeviceAppQosSettings>() {
@Override
public BluetoothHidDeviceAppQosSettings createFromParcel(Parcel in) {
@Override
public BluetoothHidDeviceAppQosSettings createFromParcel(Parcel in) {
return new BluetoothHidDeviceAppQosSettings(in.readInt(), in.readInt(), in.readInt(),
in.readInt(),
in.readInt(), in.readInt());
}
return new BluetoothHidDeviceAppQosSettings(in.readInt(), in.readInt(),
in.readInt(),
in.readInt(),
in.readInt(), in.readInt());
}
@Override
public BluetoothHidDeviceAppQosSettings[] newArray(int size) {
return new BluetoothHidDeviceAppQosSettings[size];
}
};
@Override
public BluetoothHidDeviceAppQosSettings[] newArray(int size) {
return new BluetoothHidDeviceAppQosSettings[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {
@@ -89,8 +88,9 @@ public final class BluetoothHidDeviceAppQosSettings implements Parcelable {
out.writeInt(delayVariation);
}
/** @return an int array representation of this instance */
public int[] toArray() {
return new int[] {
return new int[]{
serviceType, tokenRate, tokenBucketSize, peakBandwidth, latency, delayVariation
};
}

View File

@@ -19,16 +19,14 @@ package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Random;
/** @hide */
public final class BluetoothHidDeviceAppSdpSettings implements Parcelable {
final public String name;
final public String description;
final public String provider;
final public byte subclass;
final public byte[] descriptors;
public final String name;
public final String description;
public final String provider;
public final byte subclass;
public final byte[] descriptors;
public BluetoothHidDeviceAppSdpSettings(String name, String description, String provider,
byte subclass, byte[] descriptors) {
@@ -54,20 +52,20 @@ public final class BluetoothHidDeviceAppSdpSettings implements Parcelable {
}
public static final Parcelable.Creator<BluetoothHidDeviceAppSdpSettings> CREATOR =
new Parcelable.Creator<BluetoothHidDeviceAppSdpSettings>() {
new Parcelable.Creator<BluetoothHidDeviceAppSdpSettings>() {
@Override
public BluetoothHidDeviceAppSdpSettings createFromParcel(Parcel in) {
@Override
public BluetoothHidDeviceAppSdpSettings createFromParcel(Parcel in) {
return new BluetoothHidDeviceAppSdpSettings(in.readString(), in.readString(),
in.readString(), in.readByte(), in.createByteArray());
}
return new BluetoothHidDeviceAppSdpSettings(in.readString(), in.readString(),
in.readString(), in.readByte(), in.createByteArray());
}
@Override
public BluetoothHidDeviceAppSdpSettings[] newArray(int size) {
return new BluetoothHidDeviceAppSdpSettings[size];
}
};
@Override
public BluetoothHidDeviceAppSdpSettings[] newArray(int size) {
return new BluetoothHidDeviceAppSdpSettings[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {

View File

@@ -33,16 +33,14 @@ public abstract class BluetoothHidDeviceCallback {
* , but can be also unsolicited in case e.g. Bluetooth was turned off in
* which case application is unregistered automatically.
*
* @param pluggedDevice {@link BluetoothDevice} object which represents host
* that currently has Virtual Cable established with device. Only
* valid when application is registered, can be <code>null</code>
* .
* @param config {@link BluetoothHidDeviceAppConfiguration} object which
* represents token required to unregister application using
* {@link BluetoothHidDevice#unregisterApp(BluetoothHidDeviceAppConfiguration)}
* .
* @param registered <code>true</code> if application is registered,
* <code>false</code> otherwise.
* @param pluggedDevice {@link BluetoothDevice} object which represents host that currently has
* Virtual Cable established with device. Only valid when application is registered, can be
* <code>null</code>.
* @param config {@link BluetoothHidDeviceAppConfiguration} object which represents token
* required to unregister application using
* {@link BluetoothHidDevice#unregisterApp(BluetoothHidDeviceAppConfiguration)}.
* @param registered <code>true</code> if application is registered, <code>false</code>
* otherwise.
*/
public void onAppStatusChanged(BluetoothDevice pluggedDevice,
BluetoothHidDeviceAppConfiguration config, boolean registered) {
@@ -55,8 +53,8 @@ public abstract class BluetoothHidDeviceCallback {
* Application can assume than Virtual Cable is established when called with
* {@link BluetoothProfile#STATE_CONNECTED} <code>state</code>.
*
* @param device {@link BluetoothDevice} object representing host device
* which connection state was changed.
* @param device {@link BluetoothDevice} object representing host device which connection state
* was changed.
* @param state Connection state as defined in {@link BluetoothProfile}.
*/
public void onConnectionStateChanged(BluetoothDevice device, int state) {
@@ -69,10 +67,9 @@ public abstract class BluetoothHidDeviceCallback {
* {@link BluetoothHidDevice#replyReport(BluetoothDevice, byte, byte, byte[])}.
*
* @param type Requested Report Type.
* @param id Requested Report Id, can be 0 if no Report Id are defined in
* descriptor.
* @param bufferSize Requested buffer size, application shall respond with
* at least given number of bytes.
* @param id Requested Report Id, can be 0 if no Report Id are defined in descriptor.
* @param bufferSize Requested buffer size, application shall respond with at least given number
* of bytes.
*/
public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) {
Log.d(TAG, "onGetReport: device=" + device + " type=" + type + " id=" + id + " bufferSize="

View File

@@ -35,12 +35,13 @@ import java.util.List;
* This class provides the public APIs to control the Bluetooth Input
* Device Profile.
*
*<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
* <p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
* Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
* the BluetoothInputDevice proxy object.
*
*<p>Each method is protected with its appropriate permission.
*@hide
* <p>Each method is protected with its appropriate permission.
*
* @hide
*/
public final class BluetoothInputDevice implements BluetoothProfile {
private static final String TAG = "BluetoothInputDevice";
@@ -53,9 +54,9 @@ public final class BluetoothInputDevice implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -67,45 +68,46 @@ public final class BluetoothInputDevice implements BluetoothProfile {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
/**
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PROTOCOL_MODE_CHANGED =
"android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED";
"android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED";
/**
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_HANDSHAKE =
"android.bluetooth.input.profile.action.HANDSHAKE";
"android.bluetooth.input.profile.action.HANDSHAKE";
/**
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_REPORT =
"android.bluetooth.input.profile.action.REPORT";
"android.bluetooth.input.profile.action.REPORT";
/**
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_VIRTUAL_UNPLUG_STATUS =
"android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
"android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
/**
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_IDLE_TIME_CHANGED =
"android.bluetooth.input.profile.action.IDLE_TIME_CHANGED";
"android.bluetooth.input.profile.action.IDLE_TIME_CHANGED";
/**
* Return codes for the connect and disconnect Bluez / Dbus calls.
*
* @hide
*/
public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
@@ -174,22 +176,26 @@ public final class BluetoothInputDevice implements BluetoothProfile {
/**
* @hide
*/
public static final String EXTRA_PROTOCOL_MODE = "android.bluetooth.BluetoothInputDevice.extra.PROTOCOL_MODE";
public static final String EXTRA_PROTOCOL_MODE =
"android.bluetooth.BluetoothInputDevice.extra.PROTOCOL_MODE";
/**
* @hide
*/
public static final String EXTRA_REPORT_TYPE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_TYPE";
public static final String EXTRA_REPORT_TYPE =
"android.bluetooth.BluetoothInputDevice.extra.REPORT_TYPE";
/**
* @hide
*/
public static final String EXTRA_REPORT_ID = "android.bluetooth.BluetoothInputDevice.extra.REPORT_ID";
public static final String EXTRA_REPORT_ID =
"android.bluetooth.BluetoothInputDevice.extra.REPORT_ID";
/**
* @hide
*/
public static final String EXTRA_REPORT_BUFFER_SIZE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_BUFFER_SIZE";
public static final String EXTRA_REPORT_BUFFER_SIZE =
"android.bluetooth.BluetoothInputDevice.extra.REPORT_BUFFER_SIZE";
/**
* @hide
@@ -204,51 +210,52 @@ public final class BluetoothInputDevice implements BluetoothProfile {
/**
* @hide
*/
public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS";
public static final String EXTRA_VIRTUAL_UNPLUG_STATUS =
"android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS";
/**
* @hide
*/
public static final String EXTRA_IDLE_TIME = "android.bluetooth.BluetoothInputDevice.extra.IDLE_TIME";
public static final String EXTRA_IDLE_TIME =
"android.bluetooth.BluetoothInputDevice.extra.IDLE_TIME";
private Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
private IBluetoothInputDevice mService;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
* Create a BluetoothInputDevice proxy object for interacting with the local
* Bluetooth Service which handles the InputDevice profile
*
*/
/*package*/ BluetoothInputDevice(Context context, ServiceListener l) {
mContext = context;
@@ -260,7 +267,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -286,7 +293,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -296,9 +303,9 @@ public final class BluetoothInputDevice implements BluetoothProfile {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
mServiceListener = null;
}
@@ -319,8 +326,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean connect(BluetoothDevice device) {
@@ -359,8 +365,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean disconnect(BluetoothDevice device) {
@@ -380,6 +385,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
if (mService != null && isEnabled()) {
@@ -397,6 +403,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
if (mService != null && isEnabled()) {
@@ -414,6 +421,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
if (mService != null && isEnabled() && isValidDevice(device)) {
@@ -432,7 +440,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* Set priority of the profile
*
* <p> The device should already be paired.
* Priority can be one of {@link #PRIORITY_ON} or
* Priority can be one of {@link #PRIORITY_ON} or
* {@link #PRIORITY_OFF},
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
@@ -446,9 +454,9 @@ public final class BluetoothInputDevice implements BluetoothProfile {
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
if (mService != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON) {
return false;
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
return mService.setPriority(device, priority);
@@ -494,9 +502,11 @@ public final class BluetoothInputDevice implements BluetoothProfile {
mService = IBluetoothInputDevice.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this);
mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE,
BluetoothInputDevice.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
@@ -507,15 +517,15 @@ public final class BluetoothInputDevice implements BluetoothProfile {
};
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
}
@@ -525,8 +535,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean virtualUnplug(BluetoothDevice device) {
@@ -546,15 +555,14 @@ public final class BluetoothInputDevice implements BluetoothProfile {
}
/**
* Send Get_Protocol_Mode command to the connected HID input device.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
*true otherwise
* @hide
*/
* Send Get_Protocol_Mode command to the connected HID input device.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error, true otherwise
* @hide
*/
public boolean getProtocolMode(BluetoothDevice device) {
if (VDBG) log("getProtocolMode(" + device + ")");
if (mService != null && isEnabled() && isValidDevice(device)) {
@@ -566,7 +574,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
return false;
}
/**
@@ -575,8 +583,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
@@ -602,12 +609,16 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* @param reportType Report type
* @param reportId Report ID
* @param bufferSize Report receiving buffer size
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) {
if (VDBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize);
public boolean getReport(BluetoothDevice device, byte reportType, byte reportId,
int bufferSize) {
if (VDBG) {
log(
"getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId
+ "bufferSize=" + bufferSize);
}
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getReport(device, reportType, reportId, bufferSize);
@@ -628,8 +639,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* @param device Remote Bluetooth Device
* @param reportType Report type
* @param report Report receiving buffer size
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean setReport(BluetoothDevice device, byte reportType, String report) {
@@ -653,8 +663,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
*
* @param device Remote Bluetooth Device
* @param report Report to send
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean sendData(BluetoothDevice device, String report) {
@@ -677,8 +686,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean getIdleTime(BluetoothDevice device) {
@@ -702,8 +710,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
*
* @param device Remote Bluetooth Device
* @param idleTime Idle time to be set on HID Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
@@ -721,6 +728,6 @@ public final class BluetoothInputDevice implements BluetoothProfile {
}
private static void log(String msg) {
Log.d(TAG, msg);
Log.d(TAG, msg);
}
}

View File

@@ -26,8 +26,8 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -43,9 +43,9 @@ public final class BluetoothInputHost implements BluetoothProfile {
*
* <p>This intent will have 3 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -57,13 +57,12 @@ public final class BluetoothInputHost implements BluetoothProfile {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.inputhost.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.inputhost.profile.action.CONNECTION_STATE_CHANGED";
/**
* Constants representing device subclass.
*
* @see #registerApp(String, String, String, byte, byte[],
* BluetoothHidDeviceCallback)
* @see #registerApp(String, String, String, byte, byte[], BluetoothHidDeviceCallback)
*/
public static final byte SUBCLASS1_NONE = (byte) 0x00;
public static final byte SUBCLASS1_KEYBOARD = (byte) 0x40;
@@ -118,7 +117,8 @@ public final class BluetoothInputHost implements BluetoothProfile {
private BluetoothAdapter mAdapter;
private static class BluetoothHidDeviceCallbackWrapper extends IBluetoothHidDeviceCallback.Stub {
private static class BluetoothHidDeviceCallbackWrapper extends
IBluetoothHidDeviceCallback.Stub {
private BluetoothHidDeviceCallback mCallback;
@@ -163,37 +163,44 @@ public final class BluetoothInputHost implements BluetoothProfile {
}
}
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
Log.d(TAG, "onBluetoothStateChange: up=" + up);
synchronized (mConnection) {
if (!up) {
Log.d(TAG,"Unbinding service...");
if (mService != null) {
mService = null;
try {
mContext.unbindService(mConnection);
} catch (IllegalArgumentException e) {
Log.e(TAG,"onBluetoothStateChange: could not unbind service:", e);
public void onBluetoothStateChange(boolean up) {
Log.d(TAG, "onBluetoothStateChange: up=" + up);
synchronized (mConnection) {
if (!up) {
Log.d(TAG, "Unbinding service...");
if (mService != null) {
mService = null;
try {
mContext.unbindService(mConnection);
} catch (IllegalArgumentException e) {
Log.e(TAG, "onBluetoothStateChange: could not unbind service:",
e);
}
}
} else {
try {
if (mService == null) {
Log.d(TAG, "Binding HID Device service...");
doBind();
}
} catch (IllegalStateException e) {
Log.e(TAG,
"onBluetoothStateChange: could not bind to HID Dev "
+ "service: ",
e);
} catch (SecurityException e) {
Log.e(TAG,
"onBluetoothStateChange: could not bind to HID Dev "
+ "service: ",
e);
}
}
}
} else {
try {
if (mService == null) {
Log.d(TAG,"Binding HID Device service...");
doBind();
}
} catch (IllegalStateException e) {
Log.e(TAG,"onBluetoothStateChange: could not bind to HID Dev service: ", e);
} catch (SecurityException e) {
Log.e(TAG,"onBluetoothStateChange: could not bind to HID Dev service: ", e);
}
}
}
}
};
};
private ServiceConnection mConnection = new ServiceConnection() {
@@ -204,7 +211,7 @@ public final class BluetoothInputHost implements BluetoothProfile {
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.INPUT_HOST,
BluetoothInputHost.this);
BluetoothInputHost.this);
}
}
@@ -269,9 +276,9 @@ public final class BluetoothInputHost implements BluetoothProfile {
try {
mContext.unbindService(mConnection);
} catch (IllegalArgumentException e) {
Log.e(TAG,"close: could not unbind HID Dev service: ", e);
Log.e(TAG, "close: could not unbind HID Dev service: ", e);
}
}
}
}
mServiceListener = null;
@@ -280,6 +287,7 @@ public final class BluetoothInputHost implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
Log.v(TAG, "getConnectedDevices()");
@@ -299,6 +307,7 @@ public final class BluetoothInputHost implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
Log.v(TAG, "getDevicesMatchingConnectionStates(): states=" + Arrays.toString(states));
@@ -318,6 +327,7 @@ public final class BluetoothInputHost implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
Log.v(TAG, "getConnectionState(): device=" + device);
@@ -341,14 +351,11 @@ public final class BluetoothInputHost implements BluetoothProfile {
* should be unregistered using
* {@link #unregisterApp(BluetoothHidDeviceAppConfiguration)}.
*
* @param sdp {@link BluetoothHidDeviceAppSdpSettings} object of
* HID Device SDP record.
* @param inQos {@link BluetoothHidDeviceAppQosSettings} object of
* Incoming QoS Settings.
* @param outQos {@link BluetoothHidDeviceAppQosSettings} object of
* Outgoing QoS Settings.
* @param callback {@link BluetoothHidDeviceCallback} object to which
* callback messages will be sent.
* @param sdp {@link BluetoothHidDeviceAppSdpSettings} object of HID Device SDP record.
* @param inQos {@link BluetoothHidDeviceAppQosSettings} object of Incoming QoS Settings.
* @param outQos {@link BluetoothHidDeviceAppQosSettings} object of Outgoing QoS Settings.
* @param callback {@link BluetoothHidDeviceCallback} object to which callback messages will be
* sent.
* @return
*/
public boolean registerApp(BluetoothHidDeviceAppSdpSettings sdp,
@@ -366,9 +373,9 @@ public final class BluetoothInputHost implements BluetoothProfile {
if (mService != null) {
try {
BluetoothHidDeviceAppConfiguration config =
new BluetoothHidDeviceAppConfiguration();
new BluetoothHidDeviceAppConfiguration();
BluetoothHidDeviceCallbackWrapper cbw =
new BluetoothHidDeviceCallbackWrapper(callback);
new BluetoothHidDeviceCallbackWrapper(callback);
result = mService.registerApp(config, sdp, inQos, outQos, cbw);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
@@ -385,11 +392,10 @@ public final class BluetoothInputHost implements BluetoothProfile {
* new connections will be allowed until registered again using
* {@link #registerApp(String, String, String, byte, byte[], BluetoothHidDeviceCallback)}
*
* @param config {@link BluetoothHidDeviceAppConfiguration} object as
* obtained from
* {@link BluetoothHidDeviceCallback#onAppStatusChanged(BluetoothDevice,
* BluetoothHidDeviceAppConfiguration, boolean)}
*
* @param config {@link BluetoothHidDeviceAppConfiguration} object as obtained from {@link
* BluetoothHidDeviceCallback#onAppStatusChanged(BluetoothDevice,
* BluetoothHidDeviceAppConfiguration,
* boolean)}
* @return
*/
public boolean unregisterApp(BluetoothHidDeviceAppConfiguration config) {
@@ -413,8 +419,8 @@ public final class BluetoothInputHost implements BluetoothProfile {
/**
* Sends report to remote host using interrupt channel.
*
* @param id Report Id, as defined in descriptor. Can be 0 in case Report Id
* are not defined in descriptor.
* @param id Report Id, as defined in descriptor. Can be 0 in case Report Id are not defined in
* descriptor.
* @param data Report data, not including Report Id.
* @return
*/

View File

@@ -51,15 +51,14 @@ import java.io.InputStream;
* stream is detected or an exception is thrown.
*
* @return the byte read or -1 if the end of stream has been reached.
* @throws IOException
* if the stream is closed or another IOException occurs.
* @throws IOException if the stream is closed or another IOException occurs.
* @since Android 1.5
*/
public int read() throws IOException {
byte b[] = new byte[1];
byte[] b = new byte[1];
int ret = mSocket.read(b, 0, 1);
if (ret == 1) {
return (int)b[0] & 0xff;
return (int) b[0] & 0xff;
} else {
return -1;
}
@@ -69,21 +68,14 @@ import java.io.InputStream;
* Reads at most {@code length} bytes from this stream and stores them in
* the byte array {@code b} starting at {@code offset}.
*
* @param b
* the byte array in which to store the bytes read.
* @param offset
* the initial position in {@code buffer} to store the bytes
* read from this stream.
* @param length
* the maximum number of bytes to store in {@code b}.
* @return the number of bytes actually read or -1 if the end of the stream
* has been reached.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code length < 0}, or if
* {@code offset + length} is greater than the length of
* {@code b}.
* @throws IOException
* if the stream is closed or another IOException occurs.
* @param b the byte array in which to store the bytes read.
* @param offset the initial position in {@code buffer} to store the bytes read from this
* stream.
* @param length the maximum number of bytes to store in {@code b}.
* @return the number of bytes actually read or -1 if the end of the stream has been reached.
* @throws IndexOutOfBoundsException if {@code offset < 0} or {@code length < 0}, or if {@code
* offset + length} is greater than the length of {@code b}.
* @throws IOException if the stream is closed or another IOException occurs.
* @since Android 1.5
*/
public int read(byte[] b, int offset, int length) throws IOException {

View File

@@ -86,17 +86,16 @@ public final class BluetoothManager {
*
* @param device Remote bluetooth device.
* @param profile GATT or GATT_SERVER
* @return State of the profile connection. One of
* {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING},
* {@link BluetoothProfile#STATE_DISCONNECTED},
* {@link BluetoothProfile#STATE_DISCONNECTING}
* @return State of the profile connection. One of {@link BluetoothProfile#STATE_CONNECTED},
* {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED},
* {@link BluetoothProfile#STATE_DISCONNECTING}
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public int getConnectionState(BluetoothDevice device, int profile) {
if (DBG) Log.d(TAG,"getConnectionState()");
if (DBG) Log.d(TAG, "getConnectionState()");
List<BluetoothDevice> connectedDevices = getConnectedDevices(profile);
for(BluetoothDevice connectedDevice : connectedDevices) {
for (BluetoothDevice connectedDevice : connectedDevices) {
if (device.equals(connectedDevice)) {
return BluetoothProfile.STATE_CONNECTED;
}
@@ -120,7 +119,7 @@ public final class BluetoothManager {
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public List<BluetoothDevice> getConnectedDevices(int profile) {
if (DBG) Log.d(TAG,"getConnectedDevices");
if (DBG) Log.d(TAG, "getConnectedDevices");
if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
throw new IllegalArgumentException("Profile not supported: " + profile);
}
@@ -133,16 +132,15 @@ public final class BluetoothManager {
if (iGatt == null) return connectedDevices;
connectedDevices = iGatt.getDevicesMatchingConnectionStates(
new int[] { BluetoothProfile.STATE_CONNECTED });
new int[]{BluetoothProfile.STATE_CONNECTED});
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
return connectedDevices;
}
/**
*
* Get a list of devices that match any of the given connection
* states.
*
@@ -155,15 +153,14 @@ public final class BluetoothManager {
* to know the state of the local adapter.
*
* @param profile GATT or GATT_SERVER
* @param states Array of states. States can be one of
* {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING},
* {@link BluetoothProfile#STATE_DISCONNECTED},
* {@link BluetoothProfile#STATE_DISCONNECTING},
* @param states Array of states. States can be one of {@link BluetoothProfile#STATE_CONNECTED},
* {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED},
* {@link BluetoothProfile#STATE_DISCONNECTING},
* @return List of devices. The list will be empty on error.
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) {
if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates");
if (DBG) Log.d(TAG, "getDevicesMatchingConnectionStates");
if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
throw new IllegalArgumentException("Profile not supported: " + profile);
@@ -177,7 +174,7 @@ public final class BluetoothManager {
if (iGatt == null) return devices;
devices = iGatt.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
return devices;
@@ -189,14 +186,15 @@ public final class BluetoothManager {
* as the results of any other GATT server operations.
* The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
* to conduct GATT server operations.
*
* @param context App context
* @param callback GATT server callback handler that will receive asynchronous callbacks.
* @return BluetoothGattServer instance
*/
public BluetoothGattServer openGattServer(Context context,
BluetoothGattServerCallback callback) {
BluetoothGattServerCallback callback) {
return (openGattServer (context, callback, BluetoothDevice.TRANSPORT_AUTO));
return (openGattServer(context, callback, BluetoothDevice.TRANSPORT_AUTO));
}
/**
@@ -205,16 +203,17 @@ public final class BluetoothManager {
* as the results of any other GATT server operations.
* The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
* to conduct GATT server operations.
*
* @param context App context
* @param callback GATT server callback handler that will receive asynchronous callbacks.
* @param transport preferred transport for GATT connections to remote dual-mode devices
* {@link BluetoothDevice#TRANSPORT_AUTO} or
* {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
* @param transport preferred transport for GATT connections to remote dual-mode devices {@link
* BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
* BluetoothDevice#TRANSPORT_LE}
* @return BluetoothGattServer instance
* @hide
*/
public BluetoothGattServer openGattServer(Context context,
BluetoothGattServerCallback callback,int transport) {
BluetoothGattServerCallback callback, int transport) {
if (context == null || callback == null) {
throw new IllegalArgumentException("null parameter: " + context + " " + callback);
}
@@ -229,11 +228,11 @@ public final class BluetoothManager {
Log.e(TAG, "Fail to get GATT Server connection");
return null;
}
BluetoothGattServer mGattServer = new BluetoothGattServer(iGatt,transport);
BluetoothGattServer mGattServer = new BluetoothGattServer(iGatt, transport);
Boolean regStatus = mGattServer.registerCallback(callback);
return regStatus? mGattServer : null;
return regStatus ? mGattServer : null;
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
return null;
}
}

View File

@@ -16,19 +16,23 @@
package android.bluetooth;
import java.util.List;
import java.util.ArrayList;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.*;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* This class provides the APIs to control the Bluetooth MAP
* Profile.
*@hide
*
* @hide
*/
public final class BluetoothMap implements BluetoothProfile {
@@ -37,7 +41,7 @@ public final class BluetoothMap implements BluetoothProfile {
private static final boolean VDBG = false;
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
private IBluetoothMap mService;
private final Context mContext;
@@ -45,41 +49,41 @@ public final class BluetoothMap implements BluetoothProfile {
private BluetoothAdapter mAdapter;
/** There was an error trying to obtain the state */
public static final int STATE_ERROR = -1;
public static final int STATE_ERROR = -1;
public static final int RESULT_FAILURE = 0;
public static final int RESULT_SUCCESS = 1;
/** Connection canceled before completion. */
public static final int RESULT_CANCELED = 2;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
* Create a BluetoothMap proxy object.
@@ -94,7 +98,7 @@ public final class BluetoothMap implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
doBind();
@@ -132,7 +136,7 @@ public final class BluetoothMap implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -142,7 +146,7 @@ public final class BluetoothMap implements BluetoothProfile {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
@@ -151,15 +155,18 @@ public final class BluetoothMap implements BluetoothProfile {
/**
* Get the current state of the BluetoothMap service.
* @return One of the STATE_ return codes, or STATE_ERROR if this proxy
* object is currently not connected to the Map service.
*
* @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not
* connected to the Map service.
*/
public int getState() {
if (VDBG) log("getState()");
if (mService != null) {
try {
return mService.getState();
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -169,16 +176,18 @@ public final class BluetoothMap implements BluetoothProfile {
/**
* Get the currently connected remote Bluetooth device (PCE).
* @return The remote Bluetooth device, or null if not in connected or
* connecting state, or if this proxy object is not connected to
* the Map service.
*
* @return The remote Bluetooth device, or null if not in connected or connecting state, or if
* this proxy object is not connected to the Map service.
*/
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
if (mService != null) {
try {
return mService.getClient();
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -196,7 +205,9 @@ public final class BluetoothMap implements BluetoothProfile {
if (mService != null) {
try {
return mService.isConnected(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -217,18 +228,16 @@ public final class BluetoothMap implements BluetoothProfile {
* Initiate disconnect.
*
* @param device Remote Bluetooth Device
* @return false on error,
* true otherwise
* @return false on error, true otherwise
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -240,18 +249,19 @@ public final class BluetoothMap implements BluetoothProfile {
* This is a simple heuristic that tries to guess if a device with the
* given class bits might support Map. It is not accurate for all
* devices. It tries to err on the side of false positives.
*
* @return True if this device might support Map.
*/
public static boolean doesClassMatchSink(BluetoothClass btClass) {
// TODO optimize the rule
switch (btClass.getDeviceClass()) {
case BluetoothClass.Device.COMPUTER_DESKTOP:
case BluetoothClass.Device.COMPUTER_LAPTOP:
case BluetoothClass.Device.COMPUTER_SERVER:
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
return true;
default:
return false;
case BluetoothClass.Device.COMPUTER_DESKTOP:
case BluetoothClass.Device.COMPUTER_LAPTOP:
case BluetoothClass.Device.COMPUTER_SERVER:
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
return true;
default:
return false;
}
}
@@ -300,8 +310,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getConnectionState(device);
} catch (RemoteException e) {
@@ -317,7 +326,7 @@ public final class BluetoothMap implements BluetoothProfile {
* Set priority of the profile
*
* <p> The device should already be paired.
* Priority can be one of {@link #PRIORITY_ON} or
* Priority can be one of {@link #PRIORITY_ON} or
* {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
@@ -326,11 +335,10 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON) {
return false;
if (mService != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
return mService.setPriority(device, priority);
@@ -355,8 +363,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getPriority(device);
} catch (RemoteException e) {
@@ -376,6 +383,7 @@ public final class BluetoothMap implements BluetoothProfile {
mServiceListener.onServiceConnected(BluetoothProfile.MAP, BluetoothMap.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) log("Proxy object disconnected");
mService = null;
@@ -389,17 +397,18 @@ public final class BluetoothMap implements BluetoothProfile {
Log.d(TAG, msg);
}
private boolean isEnabled() {
private boolean isEnabled() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true;
log("Bluetooth is Not enabled");
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
}

View File

@@ -72,7 +72,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
/** Connection canceled before completion. */
public static final int RESULT_CANCELED = 2;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
@@ -216,8 +216,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) Log.d(TAG, "disconnect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.disconnect(device);
} catch (RemoteException e) {
@@ -276,8 +275,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
@Override
public int getConnectionState(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getConnectionState(device);
} catch (RemoteException e) {
@@ -300,10 +298,9 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON) {
if (mService != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
@@ -329,8 +326,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getPriority(device);
} catch (RemoteException e) {
@@ -347,10 +343,10 @@ public final class BluetoothMapClient implements BluetoothProfile {
*
* Send an SMS message to either the contacts primary number or the telephone number specified.
*
* @param device Bluetooth device
* @param contacts Uri[] of the contacts
* @param message Message to be sent
* @param sentIntent intent issued when message is sent
* @param device Bluetooth device
* @param contacts Uri[] of the contacts
* @param message Message to be sent
* @param sentIntent intent issued when message is sent
* @param deliveredIntent intent issued when message is delivered
* @return true if the message is enqueued, false on error
*/
@@ -393,7 +389,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
mService = IBluetoothMapClient.Stub.asInterface(service);
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.MAP_CLIENT,
BluetoothMapClient.this);
BluetoothMapClient.this);
}
}

View File

@@ -36,7 +36,7 @@ public final class BluetoothMasInstance implements Parcelable {
@Override
public boolean equals(Object o) {
if (o instanceof BluetoothMasInstance) {
return mId == ((BluetoothMasInstance)o).mId;
return mId == ((BluetoothMasInstance) o).mId;
}
return false;
}
@@ -48,25 +48,28 @@ public final class BluetoothMasInstance implements Parcelable {
@Override
public String toString() {
return Integer.toString(mId) + ":" + mName + ":" + mChannel + ":" +
Integer.toHexString(mMsgTypes);
return Integer.toString(mId) + ":" + mName + ":" + mChannel + ":"
+ Integer.toHexString(mMsgTypes);
}
@Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<BluetoothMasInstance> CREATOR =
new Parcelable.Creator<BluetoothMasInstance>() {
public BluetoothMasInstance createFromParcel(Parcel in) {
return new BluetoothMasInstance(in.readInt(), in.readString(),
in.readInt(), in.readInt());
}
public BluetoothMasInstance[] newArray(int size) {
return new BluetoothMasInstance[size];
}
};
public BluetoothMasInstance createFromParcel(Parcel in) {
return new BluetoothMasInstance(in.readInt(), in.readString(),
in.readInt(), in.readInt());
}
public BluetoothMasInstance[] newArray(int size) {
return new BluetoothMasInstance[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mId);
out.writeString(mName);
@@ -75,10 +78,10 @@ public final class BluetoothMasInstance implements Parcelable {
}
public static final class MessageType {
public static final int EMAIL = 0x01;
public static final int SMS_GSM = 0x02;
public static final int EMAIL = 0x01;
public static final int SMS_GSM = 0x02;
public static final int SMS_CDMA = 0x04;
public static final int MMS = 0x08;
public static final int MMS = 0x08;
}
public int getId() {

View File

@@ -44,15 +44,13 @@ import java.io.OutputStream;
* Writes a single byte to this stream. Only the least significant byte of
* the integer {@code oneByte} is written to the stream.
*
* @param oneByte
* the byte to be written.
* @throws IOException
* if an error occurs while writing to this stream.
* @param oneByte the byte to be written.
* @throws IOException if an error occurs while writing to this stream.
* @since Android 1.0
*/
public void write(int oneByte) throws IOException {
byte b[] = new byte[1];
b[0] = (byte)oneByte;
byte[] b = new byte[1];
b[0] = (byte) oneByte;
mSocket.write(b, 0, 1);
}
@@ -60,19 +58,12 @@ import java.io.OutputStream;
* Writes {@code count} bytes from the byte array {@code buffer} starting
* at position {@code offset} to this stream.
*
* @param b
* the buffer to be written.
* @param offset
* the start position in {@code buffer} from where to get bytes.
* @param count
* the number of bytes from {@code buffer} to write to this
* stream.
* @throws IOException
* if an error occurs while writing to this stream.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if
* {@code offset + count} is bigger than the length of
* {@code buffer}.
* @param b the buffer to be written.
* @param offset the start position in {@code buffer} from where to get bytes.
* @param count the number of bytes from {@code buffer} to write to this stream.
* @throws IOException if an error occurs while writing to this stream.
* @throws IndexOutOfBoundsException if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is bigger than the length of {@code buffer}.
* @since Android 1.0
*/
public void write(byte[] b, int offset, int count) throws IOException {
@@ -84,15 +75,16 @@ import java.io.OutputStream;
}
mSocket.write(b, offset, count);
}
/**
* Wait until the data in sending queue is emptied. A polling version
* for flush implementation. Use it to ensure the writing data afterwards will
* be packed in the new RFCOMM frame.
* @throws IOException
* if an i/o error occurs.
*
* @throws IOException if an i/o error occurs.
* @since Android 4.2.3
*/
public void flush() throws IOException {
public void flush() throws IOException {
mSocket.flush();
}
}

View File

@@ -34,12 +34,13 @@ import java.util.List;
* This class provides the APIs to control the Bluetooth Pan
* Profile.
*
*<p>BluetoothPan is a proxy object for controlling the Bluetooth
* <p>BluetoothPan is a proxy object for controlling the Bluetooth
* Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
* the BluetoothPan proxy object.
*
*<p>Each method is protected with its appropriate permission.
*@hide
* <p>Each method is protected with its appropriate permission.
*
* @hide
*/
public final class BluetoothPan implements BluetoothProfile {
private static final String TAG = "BluetoothPan";
@@ -52,11 +53,11 @@ public final class BluetoothPan implements BluetoothProfile {
*
* <p>This intent will have 4 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_LOCAL_ROLE} - Which local role the remote device is
* bound to. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_LOCAL_ROLE} - Which local role the remote device is
* bound to. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -70,7 +71,7 @@ public final class BluetoothPan implements BluetoothProfile {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
/**
* Extra for {@link #ACTION_CONNECTION_STATE_CHANGED} intent
@@ -94,6 +95,7 @@ public final class BluetoothPan implements BluetoothProfile {
/**
* Return codes for the connect and disconnect Bluez / Dbus calls.
*
* @hide
*/
public static final int PAN_DISCONNECT_FAILED_NOT_CONNECTED = 1000;
@@ -126,7 +128,6 @@ public final class BluetoothPan implements BluetoothProfile {
/**
* Create a BluetoothPan proxy object for interacting with the local
* Bluetooth Service which handles the Pan profile
*
*/
/*package*/ BluetoothPan(Context context, ServiceListener l) {
mContext = context;
@@ -135,7 +136,7 @@ public final class BluetoothPan implements BluetoothProfile {
try {
mAdapter.getBluetoothManager().registerStateChangeCallback(mStateChangeCallback);
} catch (RemoteException re) {
Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re);
Log.w(TAG, "Unable to register BluetoothStateChangeCallback", re);
}
if (VDBG) Log.d(TAG, "BluetoothPan() call bindService");
doBind();
@@ -161,7 +162,7 @@ public final class BluetoothPan implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mStateChangeCallback);
} catch (RemoteException re) {
Log.w(TAG,"Unable to unregister BluetoothStateChangeCallback",re);
Log.w(TAG, "Unable to unregister BluetoothStateChangeCallback", re);
}
}
@@ -171,7 +172,7 @@ public final class BluetoothPan implements BluetoothProfile {
mPanService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
@@ -182,38 +183,41 @@ public final class BluetoothPan implements BluetoothProfile {
close();
}
final private IBluetoothStateChangeCallback mStateChangeCallback = new IBluetoothStateChangeCallback.Stub() {
private final IBluetoothStateChangeCallback mStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
@Override
public void onBluetoothStateChange(boolean on) {
// Handle enable request to bind again.
Log.d(TAG, "onBluetoothStateChange on: " + on);
if (on) {
try {
if (mPanService == null) {
if (VDBG) Log.d(TAG, "onBluetoothStateChange calling doBind()");
doBind();
}
@Override
public void onBluetoothStateChange(boolean on) {
// Handle enable request to bind again.
Log.d(TAG, "onBluetoothStateChange on: " + on);
if (on) {
try {
if (mPanService == null) {
if (VDBG) Log.d(TAG, "onBluetoothStateChange calling doBind()");
doBind();
}
} catch (IllegalStateException e) {
Log.e(TAG,"onBluetoothStateChange: could not bind to PAN service: ", e);
} catch (IllegalStateException e) {
Log.e(TAG, "onBluetoothStateChange: could not bind to PAN service: ",
e);
} catch (SecurityException e) {
Log.e(TAG,"onBluetoothStateChange: could not bind to PAN service: ", e);
}
} else {
if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mPanService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
} catch (SecurityException e) {
Log.e(TAG, "onBluetoothStateChange: could not bind to PAN service: ",
e);
}
} else {
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mPanService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG, "", re);
}
}
}
}
}
}
};
};
/**
* Initiate connection to a profile of the remote bluetooth device.
@@ -229,14 +233,12 @@ public final class BluetoothPan implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
if (mPanService != null && isEnabled() &&
isValidDevice(device)) {
if (mPanService != null && isEnabled() && isValidDevice(device)) {
try {
return mPanService.connect(device);
} catch (RemoteException e) {
@@ -270,14 +272,12 @@ public final class BluetoothPan implements BluetoothProfile {
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @return false on immediate error, true otherwise
* @hide
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
if (mPanService != null && isEnabled() &&
isValidDevice(device)) {
if (mPanService != null && isEnabled() && isValidDevice(device)) {
try {
return mPanService.disconnect(device);
} catch (RemoteException e) {
@@ -292,6 +292,7 @@ public final class BluetoothPan implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
if (mPanService != null && isEnabled()) {
@@ -309,6 +310,7 @@ public final class BluetoothPan implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
if (mPanService != null && isEnabled()) {
@@ -326,10 +328,11 @@ public final class BluetoothPan implements BluetoothProfile {
/**
* {@inheritDoc}
*/
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
if (mPanService != null && isEnabled()
&& isValidDevice(device)) {
&& isValidDevice(device)) {
try {
return mPanService.getConnectionState(device);
} catch (RemoteException e) {
@@ -373,9 +376,10 @@ public final class BluetoothPan implements BluetoothProfile {
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.PAN,
BluetoothPan.this);
BluetoothPan.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "BluetoothPAN Proxy object disconnected");
mPanService = null;
@@ -386,18 +390,18 @@ public final class BluetoothPan implements BluetoothProfile {
};
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
if (device == null) return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
return false;
}
private static void log(String msg) {
Log.d(TAG, msg);
Log.d(TAG, msg);
}
}

View File

@@ -20,8 +20,8 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.RemoteException;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
/**
@@ -55,17 +55,18 @@ public class BluetoothPbap {
/** int extra for PBAP_STATE_CHANGED_ACTION */
public static final String PBAP_STATE =
"android.bluetooth.pbap.intent.PBAP_STATE";
"android.bluetooth.pbap.intent.PBAP_STATE";
/** int extra for PBAP_STATE_CHANGED_ACTION */
public static final String PBAP_PREVIOUS_STATE =
"android.bluetooth.pbap.intent.PBAP_PREVIOUS_STATE";
"android.bluetooth.pbap.intent.PBAP_PREVIOUS_STATE";
/** Indicates the state of a pbap connection state has changed.
* This intent will always contain PBAP_STATE, PBAP_PREVIOUS_STATE and
* BluetoothIntent.ADDRESS extras.
/**
* Indicates the state of a pbap connection state has changed.
* This intent will always contain PBAP_STATE, PBAP_PREVIOUS_STATE and
* BluetoothIntent.ADDRESS extras.
*/
public static final String PBAP_STATE_CHANGED_ACTION =
"android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED";
"android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED";
private IBluetoothPbap mService;
private final Context mContext;
@@ -73,13 +74,13 @@ public class BluetoothPbap {
private BluetoothAdapter mAdapter;
/** There was an error trying to obtain the state */
public static final int STATE_ERROR = -1;
public static final int STATE_ERROR = -1;
/** No client currently connected */
public static final int STATE_DISCONNECTED = 0;
/** Connection attempt in progress */
public static final int STATE_CONNECTING = 1;
public static final int STATE_CONNECTING = 1;
/** Client is currently connected */
public static final int STATE_CONNECTED = 2;
public static final int STATE_CONNECTED = 2;
public static final int RESULT_FAILURE = 0;
public static final int RESULT_SUCCESS = 1;
@@ -109,34 +110,34 @@ public class BluetoothPbap {
public void onServiceDisconnected();
}
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
* Create a BluetoothPbap proxy object.
@@ -150,7 +151,7 @@ public class BluetoothPbap {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
doBind();
@@ -188,7 +189,7 @@ public class BluetoothPbap {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -198,7 +199,7 @@ public class BluetoothPbap {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
@@ -207,15 +208,18 @@ public class BluetoothPbap {
/**
* Get the current state of the BluetoothPbap service.
* @return One of the STATE_ return codes, or STATE_ERROR if this proxy
* object is currently not connected to the Pbap service.
*
* @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not
* connected to the Pbap service.
*/
public int getState() {
if (VDBG) log("getState()");
if (mService != null) {
try {
return mService.getState();
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -225,16 +229,18 @@ public class BluetoothPbap {
/**
* Get the currently connected remote Bluetooth device (PCE).
* @return The remote Bluetooth device, or null if not in connected or
* connecting state, or if this proxy object is not connected to
* the Pbap service.
*
* @return The remote Bluetooth device, or null if not in connected or connecting state, or if
* this proxy object is not connected to the Pbap service.
*/
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
if (mService != null) {
try {
return mService.getClient();
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -252,7 +258,9 @@ public class BluetoothPbap {
if (mService != null) {
try {
return mService.isConnected(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -271,7 +279,9 @@ public class BluetoothPbap {
try {
mService.disconnect();
return true;
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -284,18 +294,19 @@ public class BluetoothPbap {
* This is a simple heuristic that tries to guess if a device with the
* given class bits might support PBAP. It is not accurate for all
* devices. It tries to err on the side of false positives.
*
* @return True if this device might support PBAP.
*/
public static boolean doesClassMatchSink(BluetoothClass btClass) {
// TODO optimize the rule
switch (btClass.getDeviceClass()) {
case BluetoothClass.Device.COMPUTER_DESKTOP:
case BluetoothClass.Device.COMPUTER_LAPTOP:
case BluetoothClass.Device.COMPUTER_SERVER:
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
return true;
default:
return false;
case BluetoothClass.Device.COMPUTER_DESKTOP:
case BluetoothClass.Device.COMPUTER_LAPTOP:
case BluetoothClass.Device.COMPUTER_SERVER:
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
return true;
default:
return false;
}
}
@@ -307,6 +318,7 @@ public class BluetoothPbap {
mServiceListener.onServiceConnected(BluetoothPbap.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) log("Proxy object disconnected");
mService = null;

View File

@@ -16,20 +16,22 @@
package android.bluetooth;
import java.util.List;
import java.util.ArrayList;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.RemoteException;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* This class provides the APIs to control the Bluetooth PBAP Client Profile.
*@hide
*
* @hide
*/
public final class BluetoothPbapClient implements BluetoothProfile {
@@ -38,7 +40,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
private static final boolean VDBG = false;
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
private IBluetoothPbapClient mService;
private final Context mContext;
@@ -46,14 +48,14 @@ public final class BluetoothPbapClient implements BluetoothProfile {
private BluetoothAdapter mAdapter;
/** There was an error trying to obtain the state */
public static final int STATE_ERROR = -1;
public static final int STATE_ERROR = -1;
public static final int RESULT_FAILURE = 0;
public static final int RESULT_SUCCESS = 1;
/** Connection canceled before completion. */
public static final int RESULT_CANCELED = 2;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) {
@@ -61,14 +63,14 @@ public final class BluetoothPbapClient implements BluetoothProfile {
}
if (!up) {
if (VDBG) {
Log.d(TAG,"Unbinding service...");
Log.d(TAG, "Unbinding service...");
}
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
} else {
@@ -76,17 +78,17 @@ public final class BluetoothPbapClient implements BluetoothProfile {
try {
if (mService == null) {
if (VDBG) {
Log.d(TAG,"Binding service...");
Log.d(TAG, "Binding service...");
}
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
* Create a BluetoothPbapClient proxy object.
@@ -103,7 +105,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
doBind();
@@ -141,7 +143,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -151,7 +153,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
@@ -163,9 +165,9 @@ public final class BluetoothPbapClient implements BluetoothProfile {
* Upon successful connection to remote PBAP server the Client will
* attempt to automatically download the users phonebook and call log.
*
* @param device a remote device we want connect to
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
* @param device a remote device we want connect to
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise;
*/
public boolean connect(BluetoothDevice device) {
if (DBG) {
@@ -189,20 +191,19 @@ public final class BluetoothPbapClient implements BluetoothProfile {
* Initiate disconnect.
*
* @param device Remote Bluetooth Device
* @return false on error,
* true otherwise
* @return false on error, true otherwise
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) {
log("disconnect(" + device + ")" + new Exception() );
log("disconnect(" + device + ")" + new Exception());
}
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
mService.disconnect(device);
return true;
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mService == null) {
@@ -291,9 +292,11 @@ public final class BluetoothPbapClient implements BluetoothProfile {
}
mService = IBluetoothPbapClient.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT, BluetoothPbapClient.this);
mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT,
BluetoothPbapClient.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) {
log("Proxy object disconnected");
@@ -319,20 +322,20 @@ public final class BluetoothPbapClient implements BluetoothProfile {
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) {
return false;
}
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
return true;
}
return false;
if (device == null) {
return false;
}
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
return true;
}
return false;
}
/**
* Set priority of the profile
*
* <p> The device should already be paired.
* Priority can be one of {@link #PRIORITY_ON} or
* Priority can be one of {@link #PRIORITY_ON} or
* {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
@@ -343,11 +346,10 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (DBG) {
log("setPriority(" + device + ", " + priority + ")");
}
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON) {
return false;
if (mService != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
return mService.setPriority(device, priority);

View File

@@ -46,14 +46,14 @@ public interface BluetoothProfile {
* Bluetooth device.
*/
public static final String EXTRA_PREVIOUS_STATE =
"android.bluetooth.profile.extra.PREVIOUS_STATE";
"android.bluetooth.profile.extra.PREVIOUS_STATE";
/** The profile is in disconnected state */
public static final int STATE_DISCONNECTED = 0;
public static final int STATE_DISCONNECTED = 0;
/** The profile is in connecting state */
public static final int STATE_CONNECTING = 1;
public static final int STATE_CONNECTING = 1;
/** The profile is in connected state */
public static final int STATE_CONNECTED = 2;
public static final int STATE_CONNECTED = 2;
/** The profile is in disconnecting state */
public static final int STATE_DISCONNECTING = 3;
@@ -74,18 +74,21 @@ public interface BluetoothProfile {
/**
* Input Device Profile
*
* @hide
*/
public static final int INPUT_DEVICE = 4;
/**
* PAN Profile
*
* @hide
*/
public static final int PAN = 5;
/**
* PBAP
*
* @hide
*/
public static final int PBAP = 6;
@@ -93,15 +96,16 @@ public interface BluetoothProfile {
/**
* GATT
*/
static public final int GATT = 7;
public static final int GATT = 7;
/**
* GATT_SERVER
*/
static public final int GATT_SERVER = 8;
public static final int GATT_SERVER = 8;
/**
* MAP Profile
*
* @hide
*/
public static final int MAP = 9;
@@ -114,43 +118,50 @@ public interface BluetoothProfile {
/**
* A2DP Sink Profile
*
* @hide
*/
public static final int A2DP_SINK = 11;
/**
* AVRCP Controller Profile
*
* @hide
*/
public static final int AVRCP_CONTROLLER = 12;
/**
* Headset Client - HFP HF Role
*
* @hide
*/
public static final int HEADSET_CLIENT = 16;
/**
* PBAP Client
*
* @hide
*/
public static final int PBAP_CLIENT = 17;
/**
* MAP Messaging Client Equipment (MCE)
*
* @hide
*/
public static final int MAP_CLIENT = 18;
/**
* Input Host
*
* @hide
*/
static public final int INPUT_HOST = 19;
public static final int INPUT_HOST = 19;
/**
* Max profile ID. This value should be updated whenever a new profile is added to match
* the largest value assigned to a profile.
*
* @hide
*/
public static final int MAX_PROFILE_ID = 19;
@@ -158,13 +169,15 @@ public interface BluetoothProfile {
/**
* Default priority for devices that we try to auto-connect to and
* and allow incoming connections for the profile
*
* @hide
**/
public static final int PRIORITY_AUTO_CONNECT = 1000;
/**
* Default priority for devices that allow incoming
* Default priority for devices that allow incoming
* and outgoing connections for the profile
*
* @hide
**/
public static final int PRIORITY_ON = 100;
@@ -172,14 +185,16 @@ public interface BluetoothProfile {
/**
* Default priority for devices that does not allow incoming
* connections and outgoing connections for the profile.
*
* @hide
**/
public static final int PRIORITY_OFF = 0;
/**
* Default priority when not set or when the device is unpaired
*
* @hide
* */
*/
public static final int PRIORITY_UNDEFINED = -1;
/**
@@ -199,9 +214,8 @@ public interface BluetoothProfile {
* <p> If none of the devices match any of the given states,
* an empty list will be returned.
*
* @param states Array of states. States can be one of
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
* @param states Array of states. States can be one of {@link #STATE_CONNECTED}, {@link
* #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
* @return List of devices. The list will be empty on error.
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
@@ -211,9 +225,8 @@ public interface BluetoothProfile {
* Get the current connection state of the profile
*
* @param device Remote bluetooth device.
* @return State of the profile connection. One of
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
* @return State of the profile connection. One of {@link #STATE_CONNECTED}, {@link
* #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public int getConnectionState(BluetoothDevice device);
@@ -226,18 +239,18 @@ public interface BluetoothProfile {
/**
* Called to notify the client when the proxy object has been
* connected to the service.
* @param profile - One of {@link #HEALTH}, {@link #HEADSET} or
* {@link #A2DP}
* @param proxy - One of {@link BluetoothHealth}, {@link BluetoothHeadset} or
* {@link BluetoothA2dp}
*
* @param profile - One of {@link #HEALTH}, {@link #HEADSET} or {@link #A2DP}
* @param proxy - One of {@link BluetoothHealth}, {@link BluetoothHeadset} or {@link
* BluetoothA2dp}
*/
public void onServiceConnected(int profile, BluetoothProfile proxy);
/**
* Called to notify the client that this proxy object has been
* disconnected from the service.
* @param profile - One of {@link #HEALTH}, {@link #HEADSET} or
* {@link #A2DP}
*
* @param profile - One of {@link #HEALTH}, {@link #HEADSET} or {@link #A2DP}
*/
public void onServiceDisconnected(int profile);
}

View File

@@ -16,19 +16,18 @@
package android.bluetooth;
import java.util.ArrayList;
import java.util.List;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.RemoteException;
import android.os.Binder;
import android.os.IBinder;
import android.os.ServiceManager;
import android.os.RemoteException;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* This class provides the APIs to control the Bluetooth SIM
* Access Profile (SAP).
@@ -38,6 +37,7 @@ import android.util.Log;
* the BluetoothSap proxy object.
*
* <p>Each method is protected with its appropriate permission.
*
* @hide
*/
public final class BluetoothSap implements BluetoothProfile {
@@ -51,9 +51,9 @@ public final class BluetoothSap implements BluetoothProfile {
*
* <p>This intent will have 4 extras:
* <ul>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
* <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
* </ul>
*
* <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
@@ -62,10 +62,11 @@ public final class BluetoothSap implements BluetoothProfile {
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
* receive.
*
* @hide
*/
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED";
"android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED";
private IBluetoothSap mService;
private final Context mContext;
@@ -74,50 +75,53 @@ public final class BluetoothSap implements BluetoothProfile {
/**
* There was an error trying to obtain the state.
*
* @hide
*/
public static final int STATE_ERROR = -1;
/**
* Connection state change succceeded.
*
* @hide
*/
public static final int RESULT_SUCCESS = 1;
/**
* Connection canceled before completion.
*
* @hide
*/
public static final int RESULT_CANCELED = 2;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
if (VDBG) Log.d(TAG, "Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
} else {
synchronized (mConnection) {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
if (VDBG) Log.d(TAG, "Binding service...");
doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
}
};
};
/**
* Create a BluetoothSap proxy object.
@@ -132,7 +136,7 @@ public final class BluetoothSap implements BluetoothProfile {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
doBind();
@@ -163,6 +167,7 @@ public final class BluetoothSap implements BluetoothProfile {
* Other public functions of BluetoothSap will return default error
* results once close() has been called. Multiple invocations of close()
* are ok.
*
* @hide
*/
public synchronized void close() {
@@ -171,7 +176,7 @@ public final class BluetoothSap implements BluetoothProfile {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
} catch (Exception e) {
Log.e(TAG,"",e);
Log.e(TAG, "", e);
}
}
@@ -181,7 +186,7 @@ public final class BluetoothSap implements BluetoothProfile {
mService = null;
mContext.unbindService(mConnection);
} catch (Exception re) {
Log.e(TAG,"",re);
Log.e(TAG, "", re);
}
}
}
@@ -190,8 +195,9 @@ public final class BluetoothSap implements BluetoothProfile {
/**
* Get the current state of the BluetoothSap service.
* @return One of the STATE_ return codes, or STATE_ERROR if this proxy
* object is currently not connected to the Sap service.
*
* @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not
* connected to the Sap service.
* @hide
*/
public int getState() {
@@ -199,7 +205,9 @@ public final class BluetoothSap implements BluetoothProfile {
if (mService != null) {
try {
return mService.getState();
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -209,9 +217,9 @@ public final class BluetoothSap implements BluetoothProfile {
/**
* Get the currently connected remote Bluetooth device (PCE).
* @return The remote Bluetooth device, or null if not in connected or
* connecting state, or if this proxy object is not connected to
* the Sap service.
*
* @return The remote Bluetooth device, or null if not in connected or connecting state, or if
* this proxy object is not connected to the Sap service.
* @hide
*/
public BluetoothDevice getClient() {
@@ -219,7 +227,9 @@ public final class BluetoothSap implements BluetoothProfile {
if (mService != null) {
try {
return mService.getClient();
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -231,6 +241,7 @@ public final class BluetoothSap implements BluetoothProfile {
* Returns true if the specified Bluetooth device is connected.
* Returns false if not connected, or if this proxy object is not
* currently connected to the Sap service.
*
* @hide
*/
public boolean isConnected(BluetoothDevice device) {
@@ -238,7 +249,9 @@ public final class BluetoothSap implements BluetoothProfile {
if (mService != null) {
try {
return mService.isConnected(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -249,6 +262,7 @@ public final class BluetoothSap implements BluetoothProfile {
/**
* Initiate connection. Initiation of outgoing connections is not
* supported for SAP server.
*
* @hide
*/
public boolean connect(BluetoothDevice device) {
@@ -260,19 +274,17 @@ public final class BluetoothSap implements BluetoothProfile {
* Initiate disconnect.
*
* @param device Remote Bluetooth Device
* @return false on error,
* true otherwise
* @return false on error, true otherwise
* @hide
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
@@ -327,8 +339,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getConnectionState(device);
} catch (RemoteException e) {
@@ -352,11 +363,10 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF &&
priority != BluetoothProfile.PRIORITY_ON) {
return false;
if (mService != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
return mService.setPriority(device, priority);
@@ -378,8 +388,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getPriority(device);
} catch (RemoteException e) {
@@ -399,6 +408,7 @@ public final class BluetoothSap implements BluetoothProfile {
mServiceListener.onServiceConnected(BluetoothProfile.SAP, BluetoothSap.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) log("Proxy object disconnected");
mService = null;
@@ -415,19 +425,22 @@ public final class BluetoothSap implements BluetoothProfile {
private boolean isEnabled() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON)
if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) {
return true;
}
log("Bluetooth is Not enabled");
return false;
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null)
return false;
if (device == null) {
return false;
}
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress()))
return true;
return false;
if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
return true;
}
return false;
}
}

View File

@@ -75,12 +75,13 @@ public final class BluetoothServerSocket implements Closeable {
/**
* Construct a socket for incoming connections.
* @param type type of socket
* @param auth require the remote device to be authenticated
*
* @param type type of socket
* @param auth require the remote device to be authenticated
* @param encrypt require the connection to be encrypted
* @param port remote port
* @throws IOException On error, for example Bluetooth not available, or
* insufficient privileges
* @param port remote port
* @throws IOException On error, for example Bluetooth not available, or insufficient
* privileges
*/
/*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
throws IOException {
@@ -93,14 +94,15 @@ public final class BluetoothServerSocket implements Closeable {
/**
* Construct a socket for incoming connections.
* @param type type of socket
* @param auth require the remote device to be authenticated
*
* @param type type of socket
* @param auth require the remote device to be authenticated
* @param encrypt require the connection to be encrypted
* @param port remote port
* @param mitm enforce man-in-the-middle protection for authentication.
* @param port remote port
* @param mitm enforce man-in-the-middle protection for authentication.
* @param min16DigitPin enforce a minimum length of 16 digits for a sec mode 2 connection
* @throws IOException On error, for example Bluetooth not available, or
* insufficient privileges
* @throws IOException On error, for example Bluetooth not available, or insufficient
* privileges
*/
/*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port,
boolean mitm, boolean min16DigitPin)
@@ -108,19 +110,20 @@ public final class BluetoothServerSocket implements Closeable {
mChannel = port;
mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null, mitm,
min16DigitPin);
if(port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
if (port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
mSocket.setExcludeSdp(true);
}
}
/**
* Construct a socket for incoming connections.
* @param type type of socket
* @param auth require the remote device to be authenticated
*
* @param type type of socket
* @param auth require the remote device to be authenticated
* @param encrypt require the connection to be encrypted
* @param uuid uuid
* @throws IOException On error, for example Bluetooth not available, or
* insufficient privileges
* @param uuid uuid
* @throws IOException On error, for example Bluetooth not available, or insufficient
* privileges
*/
/*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, ParcelUuid uuid)
throws IOException {
@@ -136,9 +139,9 @@ public final class BluetoothServerSocket implements Closeable {
* <p>Once this call returns, it can be called again to accept subsequent
* incoming connections.
* <p>{@link #close} can be used to abort this call from another thread.
*
* @return a connected {@link BluetoothSocket}
* @throws IOException on error, for example this call was aborted, or
* timeout
* @throws IOException on error, for example this call was aborted, or timeout
*/
public BluetoothSocket accept() throws IOException {
return accept(-1);
@@ -150,9 +153,9 @@ public final class BluetoothServerSocket implements Closeable {
* <p>Once this call returns, it can be called again to accept subsequent
* incoming connections.
* <p>{@link #close} can be used to abort this call from another thread.
*
* @return a connected {@link BluetoothSocket}
* @throws IOException on error, for example this call was aborted, or
* timeout
* @throws IOException on error, for example this call was aborted, or timeout
*/
public BluetoothSocket accept(int timeout) throws IOException {
return mSocket.accept(timeout);
@@ -174,16 +177,19 @@ public final class BluetoothServerSocket implements Closeable {
mSocket.close();
}
/*package*/ synchronized void setCloseHandler(Handler handler, int message) {
/*package*/
synchronized void setCloseHandler(Handler handler, int message) {
mHandler = handler;
mMessage = message;
}
/*package*/ void setServiceName(String ServiceName) {
mSocket.setServiceName(ServiceName);
/*package*/ void setServiceName(String serviceName) {
mSocket.setServiceName(serviceName);
}
/**
* Returns the channel on which this socket is bound.
*
* @hide
*/
public int getChannel() {
@@ -199,10 +205,10 @@ public final class BluetoothServerSocket implements Closeable {
* The bind operation should be conducted through this class
* and the resulting port should be kept in mChannel, and
* not set from BluetoothAdapter. */
if(mSocket != null) {
if(mSocket.getPort() != newChannel) {
Log.w(TAG,"The port set is different that the underlying port. mSocket.getPort(): "
+ mSocket.getPort() + " requested newChannel: " + newChannel);
if (mSocket != null) {
if (mSocket.getPort() != newChannel) {
Log.w(TAG, "The port set is different that the underlying port. mSocket.getPort(): "
+ mSocket.getPort() + " requested newChannel: " + newChannel);
}
}
mChannel = newChannel;
@@ -212,19 +218,16 @@ public final class BluetoothServerSocket implements Closeable {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ServerSocket: Type: ");
switch(mSocket.getConnectionType()) {
case BluetoothSocket.TYPE_RFCOMM:
{
switch (mSocket.getConnectionType()) {
case BluetoothSocket.TYPE_RFCOMM: {
sb.append("TYPE_RFCOMM");
break;
}
case BluetoothSocket.TYPE_L2CAP:
{
case BluetoothSocket.TYPE_L2CAP: {
sb.append("TYPE_L2CAP");
break;
}
case BluetoothSocket.TYPE_SCO:
{
case BluetoothSocket.TYPE_SCO: {
sb.append("TYPE_SCO");
break;
}

View File

@@ -16,25 +16,23 @@
package android.bluetooth;
import android.os.ParcelUuid;
import android.net.LocalSocket;
import android.os.ParcelFileDescriptor;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Locale;
import java.util.UUID;
import android.net.LocalSocket;
import java.nio.Buffer;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
/**
* A connected or connecting Bluetooth socket.
*
@@ -106,9 +104,9 @@ public final class BluetoothSocket implements Closeable {
/*package*/ static final int SEC_FLAG_ENCRYPT = 1;
/*package*/ static final int SEC_FLAG_AUTH = 1 << 1;
/*package*/ static final int BTSOCK_FLAG_NO_SDP = 1 << 2;
/*package*/ static final int SEC_FLAG_AUTH_MITM = 1 << 3;
/*package*/ static final int SEC_FLAG_AUTH_16_DIGIT = 1 << 4;
/*package*/ static final int BTSOCK_FLAG_NO_SDP = 1 << 2;
/*package*/ static final int SEC_FLAG_AUTH_MITM = 1 << 3;
/*package*/ static final int SEC_FLAG_AUTH_16_DIGIT = 1 << 4;
private final int mType; /* one of TYPE_RFCOMM etc */
private BluetoothDevice mDevice; /* remote device */
@@ -128,9 +126,9 @@ public final class BluetoothSocket implements Closeable {
private int mPort; /* RFCOMM channel or L2CAP psm */
private int mFd;
private String mServiceName;
private static int PROXY_CONNECTION_TIMEOUT = 5000;
private static final int PROXY_CONNECTION_TIMEOUT = 5000;
private static int SOCK_SIGNAL_SIZE = 20;
private static final int SOCK_SIGNAL_SIZE = 20;
private ByteBuffer mL2capBuffer = null;
private int mMaxTxPacketSize = 0; // The l2cap maximum packet size supported by the peer.
@@ -151,15 +149,16 @@ public final class BluetoothSocket implements Closeable {
/**
* Construct a BluetoothSocket.
* @param type type of socket
* @param fd fd to use for connected socket, or -1 for a new socket
* @param auth require the remote device to be authenticated
*
* @param type type of socket
* @param fd fd to use for connected socket, or -1 for a new socket
* @param auth require the remote device to be authenticated
* @param encrypt require the connection to be encrypted
* @param device remote device that this socket can connect to
* @param port remote port
* @param uuid SDP uuid
* @throws IOException On error, for example Bluetooth not available, or
* insufficient privileges
* @param device remote device that this socket can connect to
* @param port remote port
* @param uuid SDP uuid
* @throws IOException On error, for example Bluetooth not available, or insufficient
* privileges
*/
/*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
BluetoothDevice device, int port, ParcelUuid uuid) throws IOException {
@@ -168,21 +167,22 @@ public final class BluetoothSocket implements Closeable {
/**
* Construct a BluetoothSocket.
* @param type type of socket
* @param fd fd to use for connected socket, or -1 for a new socket
* @param auth require the remote device to be authenticated
*
* @param type type of socket
* @param fd fd to use for connected socket, or -1 for a new socket
* @param auth require the remote device to be authenticated
* @param encrypt require the connection to be encrypted
* @param device remote device that this socket can connect to
* @param port remote port
* @param uuid SDP uuid
* @param mitm enforce man-in-the-middle protection.
* @param device remote device that this socket can connect to
* @param port remote port
* @param uuid SDP uuid
* @param mitm enforce man-in-the-middle protection.
* @param min16DigitPin enforce a minimum length of 16 digits for a sec mode 2 connection
* @throws IOException On error, for example Bluetooth not available, or
* insufficient privileges
* @throws IOException On error, for example Bluetooth not available, or insufficient
* privileges
*/
/*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
BluetoothDevice device, int port, ParcelUuid uuid, boolean mitm, boolean min16DigitPin)
throws IOException {
throws IOException {
if (VDBG) Log.d(TAG, "Creating new BluetoothSocket of type: " + type);
if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && fd == -1
&& port != BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
@@ -190,9 +190,11 @@ public final class BluetoothSocket implements Closeable {
throw new IOException("Invalid RFCOMM channel: " + port);
}
}
if (uuid != null)
if (uuid != null) {
mUuid = uuid;
else mUuid = new ParcelUuid(new UUID(0, 0));
} else {
mUuid = new ParcelUuid(new UUID(0, 0));
}
mType = type;
mAuth = auth;
mAuthMitm = mitm;
@@ -214,6 +216,7 @@ public final class BluetoothSocket implements Closeable {
mInputStream = new BluetoothInputStream(this);
mOutputStream = new BluetoothOutputStream(this);
}
private BluetoothSocket(BluetoothSocket s) {
if (VDBG) Log.d(TAG, "Creating new Private BluetoothSocket of type: " + s.mType);
mUuid = s.mUuid;
@@ -231,12 +234,13 @@ public final class BluetoothSocket implements Closeable {
mAuthMitm = s.mAuthMitm;
mMin16DigitPin = s.mMin16DigitPin;
}
private BluetoothSocket acceptSocket(String RemoteAddr) throws IOException {
private BluetoothSocket acceptSocket(String remoteAddr) throws IOException {
BluetoothSocket as = new BluetoothSocket(this);
as.mSocketState = SocketState.CONNECTED;
FileDescriptor[] fds = mSocket.getAncillaryFileDescriptors();
if (DBG) Log.d(TAG, "socket fd passed by stack fds: " + Arrays.toString(fds));
if(fds == null || fds.length != 1) {
if (fds == null || fds.length != 1) {
Log.e(TAG, "socket fd passed from stack failed, fds: " + Arrays.toString(fds));
as.close();
throw new IOException("bt socket acept failed");
@@ -246,20 +250,22 @@ public final class BluetoothSocket implements Closeable {
as.mSocket = LocalSocket.createConnectedLocalSocket(fds[0]);
as.mSocketIS = as.mSocket.getInputStream();
as.mSocketOS = as.mSocket.getOutputStream();
as.mAddress = RemoteAddr;
as.mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(RemoteAddr);
as.mAddress = remoteAddr;
as.mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteAddr);
return as;
}
/**
* Construct a BluetoothSocket from address. Used by native code.
* @param type type of socket
* @param fd fd to use for connected socket, or -1 for a new socket
* @param auth require the remote device to be authenticated
*
* @param type type of socket
* @param fd fd to use for connected socket, or -1 for a new socket
* @param auth require the remote device to be authenticated
* @param encrypt require the connection to be encrypted
* @param address remote device that this socket can connect to
* @param port remote port
* @throws IOException On error, for example Bluetooth not available, or
* insufficient privileges
* @param port remote port
* @throws IOException On error, for example Bluetooth not available, or insufficient
* privileges
*/
private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
int port) throws IOException {
@@ -275,23 +281,30 @@ public final class BluetoothSocket implements Closeable {
super.finalize();
}
}
private int getSecurityFlags() {
int flags = 0;
if(mAuth)
if (mAuth) {
flags |= SEC_FLAG_AUTH;
if(mEncrypt)
}
if (mEncrypt) {
flags |= SEC_FLAG_ENCRYPT;
if(mExcludeSdp)
}
if (mExcludeSdp) {
flags |= BTSOCK_FLAG_NO_SDP;
if(mAuthMitm)
}
if (mAuthMitm) {
flags |= SEC_FLAG_AUTH_MITM;
if(mMin16DigitPin)
}
if (mMin16DigitPin) {
flags |= SEC_FLAG_AUTH_16_DIGIT;
}
return flags;
}
/**
* Get the remote device this socket is connecting, or connected, to.
*
* @return remote device
*/
public BluetoothDevice getRemoteDevice() {
@@ -303,6 +316,7 @@ public final class BluetoothSocket implements Closeable {
* <p>The input stream will be returned even if the socket is not yet
* connected, but operations on that stream will throw IOException until
* the associated socket is connected.
*
* @return InputStream
*/
public InputStream getInputStream() throws IOException {
@@ -314,6 +328,7 @@ public final class BluetoothSocket implements Closeable {
* <p>The output stream will be returned even if the socket is not yet
* connected, but operations on that stream will throw IOException until
* the associated socket is connected.
*
* @return OutputStream
*/
public OutputStream getOutputStream() throws IOException {
@@ -323,8 +338,8 @@ public final class BluetoothSocket implements Closeable {
/**
* Get the connection status of this socket, ie, whether there is an active connection with
* remote device.
* @return true if connected
* false if not connected
*
* @return true if connected false if not connected
*/
public boolean isConnected() {
return mSocketState == SocketState.CONNECTED;
@@ -349,6 +364,7 @@ public final class BluetoothSocket implements Closeable {
* {@link BluetoothAdapter#cancelDiscovery()} even if it
* did not directly request a discovery, just to be sure.
* <p>{@link #close} can be used to abort this call from another thread.
*
* @throws IOException on error, for example connection failure
*/
public void connect() throws IOException {
@@ -361,8 +377,7 @@ public final class BluetoothSocket implements Closeable {
if (bluetoothProxy == null) throw new IOException("Bluetooth is off");
mPfd = bluetoothProxy.connectSocket(mDevice, mType,
mUuid, mPort, getSecurityFlags());
synchronized(this)
{
synchronized (this) {
if (DBG) Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
if (mPfd == null) throw new IOException("bt socket connect failed");
@@ -372,14 +387,15 @@ public final class BluetoothSocket implements Closeable {
mSocketOS = mSocket.getOutputStream();
}
int channel = readInt(mSocketIS);
if (channel <= 0)
if (channel <= 0) {
throw new IOException("bt socket connect failed");
}
mPort = channel;
waitSocketSignal(mSocketIS);
synchronized(this)
{
if (mSocketState == SocketState.CLOSED)
synchronized (this) {
if (mSocketState == SocketState.CLOSED) {
throw new IOException("bt socket closed");
}
mSocketState = SocketState.CONNECTED;
}
} catch (RemoteException e) {
@@ -410,11 +426,12 @@ public final class BluetoothSocket implements Closeable {
// read out port number
try {
synchronized(this) {
if (DBG) Log.d(TAG, "bindListen(), SocketState: " + mSocketState + ", mPfd: " +
mPfd);
if(mSocketState != SocketState.INIT) return EBADFD;
if(mPfd == null) return -1;
synchronized (this) {
if (DBG) {
Log.d(TAG, "bindListen(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
}
if (mSocketState != SocketState.INIT) return EBADFD;
if (mPfd == null) return -1;
FileDescriptor fd = mPfd.getFileDescriptor();
if (fd == null) {
Log.e(TAG, "bindListen(), null file descriptor");
@@ -429,9 +446,10 @@ public final class BluetoothSocket implements Closeable {
}
if (DBG) Log.d(TAG, "bindListen(), readInt mSocketIS: " + mSocketIS);
int channel = readInt(mSocketIS);
synchronized(this) {
if(mSocketState == SocketState.INIT)
synchronized (this) {
if (mSocketState == SocketState.INIT) {
mSocketState = SocketState.LISTENING;
}
}
if (DBG) Log.d(TAG, "channel: " + channel);
if (mPort <= -1) {
@@ -455,19 +473,21 @@ public final class BluetoothSocket implements Closeable {
/*package*/ BluetoothSocket accept(int timeout) throws IOException {
BluetoothSocket acceptedSocket;
if (mSocketState != SocketState.LISTENING)
if (mSocketState != SocketState.LISTENING) {
throw new IOException("bt socket is not in listen state");
if(timeout > 0) {
}
if (timeout > 0) {
Log.d(TAG, "accept() set timeout (ms):" + timeout);
mSocket.setSoTimeout(timeout);
mSocket.setSoTimeout(timeout);
}
String RemoteAddr = waitSocketSignal(mSocketIS);
if(timeout > 0)
if (timeout > 0) {
mSocket.setSoTimeout(0);
synchronized(this)
{
if (mSocketState != SocketState.LISTENING)
}
synchronized (this) {
if (mSocketState != SocketState.LISTENING) {
throw new IOException("bt socket is not in listen state");
}
acceptedSocket = acceptSocket(RemoteAddr);
//quick drop the reference of the file handle
}
@@ -478,12 +498,13 @@ public final class BluetoothSocket implements Closeable {
if (VDBG) Log.d(TAG, "available: " + mSocketIS);
return mSocketIS.available();
}
/**
* Wait until the data in sending queue is emptied. A polling version
* for flush implementation. Used to ensure the writing data afterwards will
* be packed in new RFCOMM frame.
* @throws IOException
* if an i/o error occurs.
*
* @throws IOException if an i/o error occurs.
*/
/*package*/ void flush() throws IOException {
if (mSocketOS == null) throw new IOException("flush is called on null OutputStream");
@@ -494,11 +515,12 @@ public final class BluetoothSocket implements Closeable {
/*package*/ int read(byte[] b, int offset, int length) throws IOException {
int ret = 0;
if (VDBG) Log.d(TAG, "read in: " + mSocketIS + " len: " + length);
if(mType == TYPE_L2CAP)
{
if (mType == TYPE_L2CAP) {
int bytesToRead = length;
if (VDBG) Log.v(TAG, "l2cap: read(): offset: " + offset + " length:" + length
+ "mL2capBuffer= " + mL2capBuffer);
if (VDBG) {
Log.v(TAG, "l2cap: read(): offset: " + offset + " length:" + length
+ "mL2capBuffer= " + mL2capBuffer);
}
if (mL2capBuffer == null) {
createL2capRxBuffer();
}
@@ -511,16 +533,19 @@ public final class BluetoothSocket implements Closeable {
if (bytesToRead > mL2capBuffer.remaining()) {
bytesToRead = mL2capBuffer.remaining();
}
if(VDBG) Log.v(TAG, "get(): offset: " + offset
+ " bytesToRead: " + bytesToRead);
if (VDBG) {
Log.v(TAG, "get(): offset: " + offset
+ " bytesToRead: " + bytesToRead);
}
mL2capBuffer.get(b, offset, bytesToRead);
ret = bytesToRead;
}else {
} else {
if (VDBG) Log.v(TAG, "default: read(): offset: " + offset + " length:" + length);
ret = mSocketIS.read(b, offset, length);
}
if (ret < 0)
if (ret < 0) {
throw new IOException("bt socket closed, read return: " + ret);
}
if (VDBG) Log.d(TAG, "read out: " + mSocketIS + " ret: " + ret);
return ret;
}
@@ -532,48 +557,49 @@ public final class BluetoothSocket implements Closeable {
// splitting the write into multiple smaller writes.
// Rfcomm uses dynamic allocation, and should not have any bindings
// to the actual message length.
if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length);
if (mType == TYPE_L2CAP) {
if(length <= mMaxTxPacketSize) {
mSocketOS.write(b, offset, length);
} else {
if(DBG) Log.w(TAG, "WARNING: Write buffer larger than L2CAP packet size!\n"
if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length);
if (mType == TYPE_L2CAP) {
if (length <= mMaxTxPacketSize) {
mSocketOS.write(b, offset, length);
} else {
if (DBG) {
Log.w(TAG, "WARNING: Write buffer larger than L2CAP packet size!\n"
+ "Packet will be divided into SDU packets of size "
+ mMaxTxPacketSize);
int tmpOffset = offset;
int bytesToWrite = length;
while (bytesToWrite > 0) {
int tmpLength = (bytesToWrite > mMaxTxPacketSize)
? mMaxTxPacketSize
: bytesToWrite;
mSocketOS.write(b, tmpOffset, tmpLength);
tmpOffset += tmpLength;
bytesToWrite -= tmpLength;
}
}
} else {
mSocketOS.write(b, offset, length);
int tmpOffset = offset;
int bytesToWrite = length;
while (bytesToWrite > 0) {
int tmpLength = (bytesToWrite > mMaxTxPacketSize)
? mMaxTxPacketSize
: bytesToWrite;
mSocketOS.write(b, tmpOffset, tmpLength);
tmpOffset += tmpLength;
bytesToWrite -= tmpLength;
}
}
// There is no good way to confirm since the entire process is asynchronous anyway
if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
return length;
} else {
mSocketOS.write(b, offset, length);
}
// There is no good way to confirm since the entire process is asynchronous anyway
if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
return length;
}
@Override
public void close() throws IOException {
Log.d(TAG, "close() this: " + this + ", channel: " + mPort +
", mSocketIS: " + mSocketIS + ", mSocketOS: " + mSocketOS +
"mSocket: " + mSocket + ", mSocketState: " + mSocketState);
if(mSocketState == SocketState.CLOSED)
Log.d(TAG, "close() this: " + this + ", channel: " + mPort + ", mSocketIS: " + mSocketIS
+ ", mSocketOS: " + mSocketOS + "mSocket: " + mSocket + ", mSocketState: "
+ mSocketState);
if (mSocketState == SocketState.CLOSED) {
return;
else
{
synchronized(this)
{
if(mSocketState == SocketState.CLOSED)
} else {
synchronized (this) {
if (mSocketState == SocketState.CLOSED) {
return;
mSocketState = SocketState.CLOSED;
if(mSocket != null) {
}
mSocketState = SocketState.CLOSED;
if (mSocket != null) {
if (DBG) Log.d(TAG, "Closing mSocket: " + mSocket);
mSocket.shutdownInput();
mSocket.shutdownOutput();
@@ -584,7 +610,7 @@ public final class BluetoothSocket implements Closeable {
mPfd.close();
mPfd = null;
}
}
}
}
}
@@ -599,9 +625,10 @@ public final class BluetoothSocket implements Closeable {
* Get the maximum supported Transmit packet size for the underlying transport.
* Use this to optimize the writes done to the output socket, to avoid sending
* half full packets.
*
* @return the maximum supported Transmit packet size for the underlying transport.
*/
public int getMaxTransmitPacketSize(){
public int getMaxTransmitPacketSize() {
return mMaxTxPacketSize;
}
@@ -610,14 +637,16 @@ public final class BluetoothSocket implements Closeable {
* Use this to optimize the reads done on the input stream, as any call to read
* will return a maximum of this amount of bytes - or for some transports a
* multiple of this value.
*
* @return the maximum supported Receive packet size for the underlying transport.
*/
public int getMaxReceivePacketSize(){
public int getMaxReceivePacketSize() {
return mMaxRxPacketSize;
}
/**
* Get the type of the underlying connection.
*
* @return one of {@link #TYPE_RFCOMM}, {@link #TYPE_SCO} or {@link #TYPE_L2CAP}
*/
public int getConnectionType() {
@@ -627,67 +656,77 @@ public final class BluetoothSocket implements Closeable {
/**
* Change if a SDP entry should be automatically created.
* Must be called before calling .bind, for the call to have any effect.
* @param mExcludeSdp <li>TRUE - do not auto generate SDP record.
* <li>FALSE - default - auto generate SPP SDP record.
*
* @param excludeSdp <li>TRUE - do not auto generate SDP record. <li>FALSE - default - auto
* generate SPP SDP record.
* @hide
*/
public void setExcludeSdp(boolean excludeSdp) {
this.mExcludeSdp = excludeSdp;
mExcludeSdp = excludeSdp;
}
private String convertAddr(final byte[] addr) {
private String convertAddr(final byte[] addr) {
return String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
addr[0] , addr[1], addr[2], addr[3] , addr[4], addr[5]);
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
}
private String waitSocketSignal(InputStream is) throws IOException {
byte [] sig = new byte[SOCK_SIGNAL_SIZE];
byte[] sig = new byte[SOCK_SIGNAL_SIZE];
int ret = readAll(is, sig);
if (VDBG) Log.d(TAG, "waitSocketSignal read " + SOCK_SIGNAL_SIZE +
" bytes signal ret: " + ret);
if (VDBG) {
Log.d(TAG, "waitSocketSignal read " + SOCK_SIGNAL_SIZE + " bytes signal ret: " + ret);
}
ByteBuffer bb = ByteBuffer.wrap(sig);
/* the struct in native is decorated with __attribute__((packed)), hence this is possible */
bb.order(ByteOrder.nativeOrder());
int size = bb.getShort();
if(size != SOCK_SIGNAL_SIZE)
if (size != SOCK_SIGNAL_SIZE) {
throw new IOException("Connection failure, wrong signal size: " + size);
byte [] addr = new byte[6];
}
byte[] addr = new byte[6];
bb.get(addr);
int channel = bb.getInt();
int status = bb.getInt();
mMaxTxPacketSize = (bb.getShort() & 0xffff); // Convert to unsigned value
mMaxRxPacketSize = (bb.getShort() & 0xffff); // Convert to unsigned value
String RemoteAddr = convertAddr(addr);
if (VDBG) Log.d(TAG, "waitSocketSignal: sig size: " + size + ", remote addr: "
+ RemoteAddr + ", channel: " + channel + ", status: " + status
+ " MaxRxPktSize: " + mMaxRxPacketSize + " MaxTxPktSize: " + mMaxTxPacketSize);
if(status != 0)
if (VDBG) {
Log.d(TAG, "waitSocketSignal: sig size: " + size + ", remote addr: "
+ RemoteAddr + ", channel: " + channel + ", status: " + status
+ " MaxRxPktSize: " + mMaxRxPacketSize + " MaxTxPktSize: " + mMaxTxPacketSize);
}
if (status != 0) {
throw new IOException("Connection failure, status: " + status);
}
return RemoteAddr;
}
private void createL2capRxBuffer(){
if(mType == TYPE_L2CAP) {
private void createL2capRxBuffer() {
if (mType == TYPE_L2CAP) {
// Allocate the buffer to use for reads.
if(VDBG) Log.v(TAG, " Creating mL2capBuffer: mMaxPacketSize: " + mMaxRxPacketSize);
if (VDBG) Log.v(TAG, " Creating mL2capBuffer: mMaxPacketSize: " + mMaxRxPacketSize);
mL2capBuffer = ByteBuffer.wrap(new byte[mMaxRxPacketSize]);
if(VDBG) Log.v(TAG, "mL2capBuffer.remaining()" + mL2capBuffer.remaining());
if (VDBG) Log.v(TAG, "mL2capBuffer.remaining()" + mL2capBuffer.remaining());
mL2capBuffer.limit(0); // Ensure we do a real read at the first read-request
if(VDBG) Log.v(TAG, "mL2capBuffer.remaining() after limit(0):" +
mL2capBuffer.remaining());
if (VDBG) {
Log.v(TAG, "mL2capBuffer.remaining() after limit(0):" + mL2capBuffer.remaining());
}
}
}
private int readAll(InputStream is, byte[] b) throws IOException {
int left = b.length;
while(left > 0) {
while (left > 0) {
int ret = is.read(b, b.length - left, left);
if(ret <= 0)
throw new IOException("read failed, socket might closed or timeout, read ret: "
+ ret);
if (ret <= 0) {
throw new IOException("read failed, socket might closed or timeout, read ret: "
+ ret);
}
left -= ret;
if(left != 0)
Log.w(TAG, "readAll() looping, read partial size: " + (b.length - left) +
", expect size: " + b.length);
if (left != 0) {
Log.w(TAG, "readAll() looping, read partial size: " + (b.length - left)
+ ", expect size: " + b.length);
}
}
return b.length;
}
@@ -704,7 +743,7 @@ public final class BluetoothSocket implements Closeable {
private int fillL2capRxBuffer() throws IOException {
mL2capBuffer.rewind();
int ret = mSocketIS.read(mL2capBuffer.array());
if(ret == -1) {
if (ret == -1) {
// reached end of stream - return -1
mL2capBuffer.limit(0);
return -1;

View File

@@ -25,9 +25,10 @@ import java.util.HashSet;
import java.util.UUID;
/**
* Static helper methods and constants to decode the ParcelUuid of remote devices.
* @hide
*/
* Static helper methods and constants to decode the ParcelUuid of remote devices.
*
* @hide
*/
public final class BluetoothUuid {
/* See Bluetooth Assigned Numbers document - SDP section, to get the values of UUIDs
@@ -76,9 +77,9 @@ public final class BluetoothUuid {
ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid MAS =
ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid SAP =
public static final ParcelUuid SAP =
ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid BASE_UUID =
ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
@@ -90,8 +91,8 @@ public final class BluetoothUuid {
public static final int UUID_BYTES_128_BIT = 16;
public static final ParcelUuid[] RESERVED_UUIDS = {
AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
ObexObjectPush, PANU, NAP, MAP, MNS, MAS, SAP};
AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
ObexObjectPush, PANU, NAP, MAP, MNS, MAS, SAP};
public static boolean isAudioSource(ParcelUuid uuid) {
return uuid.equals(AudioSource);
@@ -136,15 +137,19 @@ public final class BluetoothUuid {
public static boolean isBnep(ParcelUuid uuid) {
return uuid.equals(BNEP);
}
public static boolean isMap(ParcelUuid uuid) {
return uuid.equals(MAP);
}
public static boolean isMns(ParcelUuid uuid) {
return uuid.equals(MNS);
}
public static boolean isMas(ParcelUuid uuid) {
return uuid.equals(MAS);
}
public static boolean isSap(ParcelUuid uuid) {
return uuid.equals(SAP);
}
@@ -156,13 +161,15 @@ public final class BluetoothUuid {
* @param uuid
*/
public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) {
if ((uuidArray == null || uuidArray.length == 0) && uuid == null)
if ((uuidArray == null || uuidArray.length == 0) && uuid == null) {
return true;
}
if (uuidArray == null)
if (uuidArray == null) {
return false;
}
for (ParcelUuid element: uuidArray) {
for (ParcelUuid element : uuidArray) {
if (element.equals(uuid)) return true;
}
return false;
@@ -173,21 +180,20 @@ public final class BluetoothUuid {
*
* @param uuidA - List of ParcelUuids
* @param uuidB - List of ParcelUuids
*
*/
public static boolean containsAnyUuid(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
if (uuidA == null && uuidB == null) return true;
if (uuidA == null) {
return uuidB.length == 0 ? true : false;
return uuidB.length == 0;
}
if (uuidB == null) {
return uuidA.length == 0 ? true : false;
return uuidA.length == 0;
}
HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
for (ParcelUuid uuid: uuidB) {
HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid>(Arrays.asList(uuidA));
for (ParcelUuid uuid : uuidB) {
if (uuidSet.contains(uuid)) return true;
}
return false;
@@ -199,19 +205,18 @@ public final class BluetoothUuid {
*
* @param uuidA - Array of ParcelUuidsA
* @param uuidB - Array of ParcelUuidsB
*
*/
public static boolean containsAllUuids(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
if (uuidA == null && uuidB == null) return true;
if (uuidA == null) {
return uuidB.length == 0 ? true : false;
return uuidB.length == 0;
}
if (uuidB == null) return true;
HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
for (ParcelUuid uuid: uuidB) {
HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid>(Arrays.asList(uuidA));
for (ParcelUuid uuid : uuidB) {
if (!uuidSet.contains(uuid)) return false;
}
return true;
@@ -221,13 +226,14 @@ public final class BluetoothUuid {
* Extract the Service Identifier or the actual uuid from the Parcel Uuid.
* For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid,
* this function will return 110B
*
* @param parcelUuid
* @return the service identifier.
*/
public static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
UUID uuid = parcelUuid.getUuid();
long value = (uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32;
return (int)value;
return (int) value;
}
/**
@@ -244,8 +250,8 @@ public final class BluetoothUuid {
throw new IllegalArgumentException("uuidBytes cannot be null");
}
int length = uuidBytes.length;
if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT &&
length != UUID_BYTES_128_BIT) {
if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT
&& length != UUID_BYTES_128_BIT) {
throw new IllegalArgumentException("uuidBytes length invalid - " + length);
}
@@ -264,7 +270,7 @@ public final class BluetoothUuid {
shortUuid = uuidBytes[0] & 0xFF;
shortUuid += (uuidBytes[1] & 0xFF) << 8;
} else {
shortUuid = uuidBytes[0] & 0xFF ;
shortUuid = uuidBytes[0] & 0xFF;
shortUuid += (uuidBytes[1] & 0xFF) << 8;
shortUuid += (uuidBytes[2] & 0xFF) << 16;
shortUuid += (uuidBytes[3] & 0xFF) << 24;
@@ -275,8 +281,8 @@ public final class BluetoothUuid {
}
/**
* Parse UUID to bytes. The returned value is shortest representation, a 16-bit, 32-bit or 128-bit UUID,
* Note returned value is little endian (Bluetooth).
* Parse UUID to bytes. The returned value is shortest representation, a 16-bit, 32-bit or
* 128-bit UUID, Note returned value is little endian (Bluetooth).
*
* @param uuid uuid to parse.
* @return shortest representation of {@code uuid} as bytes.
@@ -290,18 +296,18 @@ public final class BluetoothUuid {
if (is16BitUuid(uuid)) {
byte[] uuidBytes = new byte[UUID_BYTES_16_BIT];
int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
uuidBytes[0] = (byte)(uuidVal & 0xFF);
uuidBytes[1] = (byte)((uuidVal & 0xFF00) >> 8);
uuidBytes[0] = (byte) (uuidVal & 0xFF);
uuidBytes[1] = (byte) ((uuidVal & 0xFF00) >> 8);
return uuidBytes;
}
if (is32BitUuid(uuid)) {
byte[] uuidBytes = new byte[UUID_BYTES_32_BIT];
int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
uuidBytes[0] = (byte)(uuidVal & 0xFF);
uuidBytes[1] = (byte)((uuidVal & 0xFF00) >> 8);
uuidBytes[2] = (byte)((uuidVal & 0xFF0000) >> 16);
uuidBytes[3] = (byte)((uuidVal & 0xFF000000) >> 24);
uuidBytes[0] = (byte) (uuidVal & 0xFF);
uuidBytes[1] = (byte) ((uuidVal & 0xFF00) >> 8);
uuidBytes[2] = (byte) ((uuidVal & 0xFF0000) >> 16);
uuidBytes[3] = (byte) ((uuidVal & 0xFF000000) >> 24);
return uuidBytes;
}

View File

@@ -19,8 +19,6 @@ package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
/**
* Out Of Band Data for Bluetooth device pairing.
*
@@ -30,13 +28,13 @@ import android.util.Log;
* @hide
*/
public class OobData implements Parcelable {
private byte[] leBluetoothDeviceAddress;
private byte[] securityManagerTk;
private byte[] leSecureConnectionsConfirmation;
private byte[] leSecureConnectionsRandom;
private byte[] mLeBluetoothDeviceAddress;
private byte[] mSecurityManagerTk;
private byte[] mLeSecureConnectionsConfirmation;
private byte[] mLeSecureConnectionsRandom;
public byte[] getLeBluetoothDeviceAddress() {
return leBluetoothDeviceAddress;
return mLeBluetoothDeviceAddress;
}
/**
@@ -45,11 +43,11 @@ public class OobData implements Parcelable {
* a detailed description.
*/
public void setLeBluetoothDeviceAddress(byte[] leBluetoothDeviceAddress) {
this.leBluetoothDeviceAddress = leBluetoothDeviceAddress;
mLeBluetoothDeviceAddress = leBluetoothDeviceAddress;
}
public byte[] getSecurityManagerTk() {
return securityManagerTk;
return mSecurityManagerTk;
}
/**
@@ -58,48 +56,50 @@ public class OobData implements Parcelable {
* Part A 1.8 for a detailed description.
*/
public void setSecurityManagerTk(byte[] securityManagerTk) {
this.securityManagerTk = securityManagerTk;
mSecurityManagerTk = securityManagerTk;
}
public byte[] getLeSecureConnectionsConfirmation() {
return leSecureConnectionsConfirmation;
return mLeSecureConnectionsConfirmation;
}
public void setLeSecureConnectionsConfirmation(byte[] leSecureConnectionsConfirmation) {
this.leSecureConnectionsConfirmation = leSecureConnectionsConfirmation;
mLeSecureConnectionsConfirmation = leSecureConnectionsConfirmation;
}
public byte[] getLeSecureConnectionsRandom() {
return leSecureConnectionsRandom;
return mLeSecureConnectionsRandom;
}
public void setLeSecureConnectionsRandom(byte[] leSecureConnectionsRandom) {
this.leSecureConnectionsRandom = leSecureConnectionsRandom;
mLeSecureConnectionsRandom = leSecureConnectionsRandom;
}
public OobData() { }
public OobData() {
}
private OobData(Parcel in) {
leBluetoothDeviceAddress = in.createByteArray();
securityManagerTk = in.createByteArray();
leSecureConnectionsConfirmation = in.createByteArray();
leSecureConnectionsRandom = in.createByteArray();
mLeBluetoothDeviceAddress = in.createByteArray();
mSecurityManagerTk = in.createByteArray();
mLeSecureConnectionsConfirmation = in.createByteArray();
mLeSecureConnectionsRandom = in.createByteArray();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeByteArray(leBluetoothDeviceAddress);
out.writeByteArray(securityManagerTk);
out.writeByteArray(leSecureConnectionsConfirmation);
out.writeByteArray(leSecureConnectionsRandom);
out.writeByteArray(mLeBluetoothDeviceAddress);
out.writeByteArray(mSecurityManagerTk);
out.writeByteArray(mLeSecureConnectionsConfirmation);
out.writeByteArray(mLeSecureConnectionsRandom);
}
public static final Parcelable.Creator<OobData> CREATOR
= new Parcelable.Creator<OobData>() {
public static final Parcelable.Creator<OobData> CREATOR =
new Parcelable.Creator<OobData>() {
public OobData createFromParcel(Parcel in) {
return new OobData(in);
}
@@ -108,4 +108,4 @@ public class OobData implements Parcelable {
return new OobData[size];
}
};
}
}

View File

@@ -26,38 +26,41 @@ public class SdpMasRecord implements Parcelable {
private final int mSupportedFeatures;
private final int mSupportedMessageTypes;
private final String mServiceName;
/** Message type */
public static final class MessageType {
public static final int EMAIL = 0x01;
public static final int SMS_GSM = 0x02;
public static final int EMAIL = 0x01;
public static final int SMS_GSM = 0x02;
public static final int SMS_CDMA = 0x04;
public static final int MMS = 0x08;
public static final int MMS = 0x08;
}
public SdpMasRecord(int mas_instance_id,
int l2cap_psm,
int rfcomm_channel_number,
int profile_version,
int supported_features,
int supported_message_types,
String service_name){
this.mMasInstanceId = mas_instance_id;
this.mL2capPsm = l2cap_psm;
this.mRfcommChannelNumber = rfcomm_channel_number;
this.mProfileVersion = profile_version;
this.mSupportedFeatures = supported_features;
this.mSupportedMessageTypes = supported_message_types;
this.mServiceName = service_name;
public SdpMasRecord(int masInstanceId,
int l2capPsm,
int rfcommChannelNumber,
int profileVersion,
int supportedFeatures,
int supportedMessageTypes,
String serviceName) {
mMasInstanceId = masInstanceId;
mL2capPsm = l2capPsm;
mRfcommChannelNumber = rfcommChannelNumber;
mProfileVersion = profileVersion;
mSupportedFeatures = supportedFeatures;
mSupportedMessageTypes = supportedMessageTypes;
mServiceName = serviceName;
}
public SdpMasRecord(Parcel in){
this.mMasInstanceId = in.readInt();
this.mL2capPsm = in.readInt();
this.mRfcommChannelNumber = in.readInt();
this.mProfileVersion = in.readInt();
this.mSupportedFeatures = in.readInt();
this.mSupportedMessageTypes = in.readInt();
this.mServiceName = in.readString();
public SdpMasRecord(Parcel in) {
mMasInstanceId = in.readInt();
mL2capPsm = in.readInt();
mRfcommChannelNumber = in.readInt();
mProfileVersion = in.readInt();
mSupportedFeatures = in.readInt();
mSupportedMessageTypes = in.readInt();
mServiceName = in.readString();
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
@@ -87,50 +90,49 @@ public class SdpMasRecord implements Parcelable {
public int getSupportedMessageTypes() {
return mSupportedMessageTypes;
}
public boolean msgSupported(int msg) {
return (mSupportedMessageTypes & msg) != 0;
}
public String getServiceName() {
return mServiceName;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.mMasInstanceId);
dest.writeInt(this.mL2capPsm);
dest.writeInt(this.mRfcommChannelNumber);
dest.writeInt(this.mProfileVersion);
dest.writeInt(this.mSupportedFeatures);
dest.writeInt(this.mSupportedMessageTypes);
dest.writeString(this.mServiceName);
dest.writeInt(mMasInstanceId);
dest.writeInt(mL2capPsm);
dest.writeInt(mRfcommChannelNumber);
dest.writeInt(mProfileVersion);
dest.writeInt(mSupportedFeatures);
dest.writeInt(mSupportedMessageTypes);
dest.writeString(mServiceName);
}
@Override
public String toString(){
public String toString() {
String ret = "Bluetooth MAS SDP Record:\n";
if(mMasInstanceId != -1){
if (mMasInstanceId != -1) {
ret += "Mas Instance Id: " + mMasInstanceId + "\n";
}
if(mRfcommChannelNumber != -1){
if (mRfcommChannelNumber != -1) {
ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
}
if(mL2capPsm != -1){
if (mL2capPsm != -1) {
ret += "L2CAP PSM: " + mL2capPsm + "\n";
}
if(mServiceName != null){
if (mServiceName != null) {
ret += "Service Name: " + mServiceName + "\n";
}
if(mProfileVersion != -1){
if (mProfileVersion != -1) {
ret += "Profile version: " + mProfileVersion + "\n";
}
if(mSupportedMessageTypes != -1){
if (mSupportedMessageTypes != -1) {
ret += "Supported msg types: " + mSupportedMessageTypes + "\n";
}
if(mSupportedFeatures != -1){
if (mSupportedFeatures != -1) {
ret += "Supported features: " + mSupportedFeatures + "\n";
}
return ret;
@@ -140,6 +142,7 @@ public class SdpMasRecord implements Parcelable {
public SdpMasRecord createFromParcel(Parcel in) {
return new SdpMasRecord(in);
}
public SdpRecord[] newArray(int size) {
return new SdpRecord[size];
}

View File

@@ -25,25 +25,26 @@ public class SdpMnsRecord implements Parcelable {
private final int mProfileVersion;
private final String mServiceName;
public SdpMnsRecord(int l2cap_psm,
int rfcomm_channel_number,
int profile_version,
int supported_features,
String service_name){
this.mL2capPsm = l2cap_psm;
this.mRfcommChannelNumber = rfcomm_channel_number;
this.mSupportedFeatures = supported_features;
this.mServiceName = service_name;
this.mProfileVersion = profile_version;
public SdpMnsRecord(int l2capPsm,
int rfcommChannelNumber,
int profileVersion,
int supportedFeatures,
String serviceName) {
mL2capPsm = l2capPsm;
mRfcommChannelNumber = rfcommChannelNumber;
mSupportedFeatures = supportedFeatures;
mServiceName = serviceName;
mProfileVersion = profileVersion;
}
public SdpMnsRecord(Parcel in){
this.mRfcommChannelNumber = in.readInt();
this.mL2capPsm = in.readInt();
this.mServiceName = in.readString();
this.mSupportedFeatures = in.readInt();
this.mProfileVersion = in.readInt();
public SdpMnsRecord(Parcel in) {
mRfcommChannelNumber = in.readInt();
mL2capPsm = in.readInt();
mServiceName = in.readString();
mSupportedFeatures = in.readInt();
mProfileVersion = in.readInt();
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
@@ -80,23 +81,23 @@ public class SdpMnsRecord implements Parcelable {
dest.writeInt(mProfileVersion);
}
public String toString(){
public String toString() {
String ret = "Bluetooth MNS SDP Record:\n";
if(mRfcommChannelNumber != -1){
if (mRfcommChannelNumber != -1) {
ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
}
if(mL2capPsm != -1){
if (mL2capPsm != -1) {
ret += "L2CAP PSM: " + mL2capPsm + "\n";
}
if(mServiceName != null){
if (mServiceName != null) {
ret += "Service Name: " + mServiceName + "\n";
}
if(mSupportedFeatures != -1){
if (mSupportedFeatures != -1) {
ret += "Supported features: " + mSupportedFeatures + "\n";
}
if(mProfileVersion != -1){
ret += "Profile_version: " + mProfileVersion+"\n";
if (mProfileVersion != -1) {
ret += "Profile_version: " + mProfileVersion + "\n";
}
return ret;
}
@@ -105,6 +106,7 @@ public class SdpMnsRecord implements Parcelable {
public SdpMnsRecord createFromParcel(Parcel in) {
return new SdpMnsRecord(in);
}
public SdpMnsRecord[] newArray(int size) {
return new SdpMnsRecord[size];
}

View File

@@ -14,14 +14,15 @@
*/
package android.bluetooth;
import java.util.Arrays;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Arrays;
/**
* Data representation of a Object Push Profile Server side SDP record.
*/
/** @hide */
public class SdpOppOpsRecord implements Parcelable {
@@ -34,11 +35,11 @@ public class SdpOppOpsRecord implements Parcelable {
public SdpOppOpsRecord(String serviceName, int rfcommChannel,
int l2capPsm, int version, byte[] formatsList) {
super();
this.mServiceName = serviceName;
this.mRfcommChannel = rfcommChannel;
this.mL2capPsm = l2capPsm;
this.mProfileVersion = version;
this.mFormatsList = formatsList;
mServiceName = serviceName;
mRfcommChannel = rfcommChannel;
mL2capPsm = l2capPsm;
mProfileVersion = version;
mFormatsList = formatsList;
}
public String getServiceName() {
@@ -67,18 +68,18 @@ public class SdpOppOpsRecord implements Parcelable {
return 0;
}
public SdpOppOpsRecord(Parcel in){
this.mRfcommChannel = in.readInt();
this.mL2capPsm = in.readInt();
this.mProfileVersion = in.readInt();
this.mServiceName = in.readString();
public SdpOppOpsRecord(Parcel in) {
mRfcommChannel = in.readInt();
mL2capPsm = in.readInt();
mProfileVersion = in.readInt();
mServiceName = in.readString();
int arrayLength = in.readInt();
if(arrayLength > 0) {
if (arrayLength > 0) {
byte[] bytes = new byte[arrayLength];
in.readByteArray(bytes);
this.mFormatsList = bytes;
mFormatsList = bytes;
} else {
this.mFormatsList = null;
mFormatsList = null;
}
}
@@ -88,7 +89,7 @@ public class SdpOppOpsRecord implements Parcelable {
dest.writeInt(mL2capPsm);
dest.writeInt(mProfileVersion);
dest.writeString(mServiceName);
if(mFormatsList!= null && mFormatsList.length > 0) {
if (mFormatsList != null && mFormatsList.length > 0) {
dest.writeInt(mFormatsList.length);
dest.writeByteArray(mFormatsList);
} else {
@@ -96,7 +97,8 @@ public class SdpOppOpsRecord implements Parcelable {
}
}
public String toString(){
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Bluetooth OPP Server SDP Record:\n");
sb.append(" RFCOMM Chan Number: ").append(mRfcommChannel);
sb.append("\n L2CAP PSM: ").append(mL2capPsm);
@@ -110,6 +112,7 @@ public class SdpOppOpsRecord implements Parcelable {
public SdpOppOpsRecord createFromParcel(Parcel in) {
return new SdpOppOpsRecord(in);
}
public SdpOppOpsRecord[] newArray(int size) {
return new SdpOppOpsRecord[size];
}

View File

@@ -27,28 +27,29 @@ public class SdpPseRecord implements Parcelable {
private final int mSupportedRepositories;
private final String mServiceName;
public SdpPseRecord(int l2cap_psm,
int rfcomm_channel_number,
int profile_version,
int supported_features,
int supported_repositories,
String service_name){
this.mL2capPsm = l2cap_psm;
this.mRfcommChannelNumber = rfcomm_channel_number;
this.mProfileVersion = profile_version;
this.mSupportedFeatures = supported_features;
this.mSupportedRepositories = supported_repositories;
this.mServiceName = service_name;
public SdpPseRecord(int l2capPsm,
int rfcommChannelNumber,
int profileVersion,
int supportedFeatures,
int supportedRepositories,
String serviceName) {
mL2capPsm = l2capPsm;
mRfcommChannelNumber = rfcommChannelNumber;
mProfileVersion = profileVersion;
mSupportedFeatures = supportedFeatures;
mSupportedRepositories = supportedRepositories;
mServiceName = serviceName;
}
public SdpPseRecord(Parcel in){
this.mRfcommChannelNumber = in.readInt();
this.mL2capPsm = in.readInt();
this.mProfileVersion = in.readInt();
this.mSupportedFeatures = in.readInt();
this.mSupportedRepositories = in.readInt();
this.mServiceName = in.readString();
public SdpPseRecord(Parcel in) {
mRfcommChannelNumber = in.readInt();
mL2capPsm = in.readInt();
mProfileVersion = in.readInt();
mSupportedFeatures = in.readInt();
mSupportedRepositories = in.readInt();
mServiceName = in.readString();
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
@@ -78,6 +79,7 @@ public class SdpPseRecord implements Parcelable {
public int getSupportedRepositories() {
return mSupportedRepositories;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mRfcommChannelNumber);
@@ -89,25 +91,26 @@ public class SdpPseRecord implements Parcelable {
}
public String toString(){
@Override
public String toString() {
String ret = "Bluetooth MNS SDP Record:\n";
if(mRfcommChannelNumber != -1){
if (mRfcommChannelNumber != -1) {
ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
}
if(mL2capPsm != -1){
if (mL2capPsm != -1) {
ret += "L2CAP PSM: " + mL2capPsm + "\n";
}
if(mProfileVersion != -1){
if (mProfileVersion != -1) {
ret += "profile version: " + mProfileVersion + "\n";
}
if(mServiceName != null){
if (mServiceName != null) {
ret += "Service Name: " + mServiceName + "\n";
}
if(mSupportedFeatures != -1){
if (mSupportedFeatures != -1) {
ret += "Supported features: " + mSupportedFeatures + "\n";
}
if(mSupportedRepositories != -1){
if (mSupportedRepositories != -1) {
ret += "Supported repositories: " + mSupportedRepositories + "\n";
}
@@ -118,6 +121,7 @@ public class SdpPseRecord implements Parcelable {
public SdpPseRecord createFromParcel(Parcel in) {
return new SdpPseRecord(in);
}
public SdpPseRecord[] newArray(int size) {
return new SdpPseRecord[size];
}

View File

@@ -21,7 +21,7 @@ import android.os.Parcelable;
import java.util.Arrays;
/** @hide */
public class SdpRecord implements Parcelable{
public class SdpRecord implements Parcelable {
private final byte[] mRawData;
private final int mRawSize;
@@ -32,15 +32,15 @@ public class SdpRecord implements Parcelable{
+ ", rawSize=" + mRawSize + "]";
}
public SdpRecord(int size_record, byte[] record){
this.mRawData = record;
this.mRawSize = size_record;
public SdpRecord(int sizeRecord, byte[] record) {
mRawData = record;
mRawSize = sizeRecord;
}
public SdpRecord(Parcel in){
this.mRawSize = in.readInt();
this.mRawData = new byte[mRawSize];
in.readByteArray(this.mRawData);
public SdpRecord(Parcel in) {
mRawSize = in.readInt();
mRawData = new byte[mRawSize];
in.readByteArray(mRawData);
}
@@ -51,11 +51,12 @@ public class SdpRecord implements Parcelable{
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.mRawSize);
dest.writeByteArray(this.mRawData);
dest.writeInt(mRawSize);
dest.writeByteArray(mRawData);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public SdpRecord createFromParcel(Parcel in) {
return new SdpRecord(in);

View File

@@ -25,23 +25,21 @@ public class SdpSapsRecord implements Parcelable {
private final int mProfileVersion;
private final String mServiceName;
public SdpSapsRecord(int rfcomm_channel_number,
int profile_version,
String service_name) {
this.mRfcommChannelNumber = rfcomm_channel_number;
this.mProfileVersion = profile_version;
this.mServiceName = service_name;
public SdpSapsRecord(int rfcommChannelNumber, int profileVersion, String serviceName) {
mRfcommChannelNumber = rfcommChannelNumber;
mProfileVersion = profileVersion;
mServiceName = serviceName;
}
public SdpSapsRecord(Parcel in) {
this.mRfcommChannelNumber = in.readInt();
this.mProfileVersion = in.readInt();
this.mServiceName = in.readString();
mRfcommChannelNumber = in.readInt();
mProfileVersion = in.readInt();
mServiceName = in.readString();
}
@Override
public int describeContents() {
return 0;
return 0;
}
public int getRfcommCannelNumber() {
@@ -58,9 +56,9 @@ public class SdpSapsRecord implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.mRfcommChannelNumber);
dest.writeInt(this.mProfileVersion);
dest.writeString(this.mServiceName);
dest.writeInt(mRfcommChannelNumber);
dest.writeInt(mProfileVersion);
dest.writeString(mServiceName);
}
@@ -84,6 +82,7 @@ public class SdpSapsRecord implements Parcelable {
public SdpSapsRecord createFromParcel(Parcel in) {
return new SdpSapsRecord(in);
}
public SdpRecord[] newArray(int size) {
return new SdpRecord[size];
}

View File

@@ -20,6 +20,7 @@ import android.os.Parcelable;
/**
* Record of data traffic (in bytes) by an application identified by its UID.
*
* @hide
*/
public class UidTraffic implements Cloneable, Parcelable {
@@ -90,11 +91,8 @@ public class UidTraffic implements Cloneable, Parcelable {
@Override
public String toString() {
return "UidTraffic{" +
"mAppUid=" + mAppUid +
", mRxBytes=" + mRxBytes +
", mTxBytes=" + mTxBytes +
'}';
return "UidTraffic{mAppUid=" + mAppUid + ", mRxBytes=" + mRxBytes + ", mTxBytes="
+ mTxBytes + '}';
}
public static final Creator<UidTraffic> CREATOR = new Creator<UidTraffic>() {

View File

@@ -58,7 +58,7 @@ public abstract class AdvertiseCallback {
* that the advertising has been started successfully.
*
* @param settingsInEffect The actual settings used for advertising, which may be different from
* what has been requested.
* what has been requested.
*/
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
}
@@ -67,7 +67,7 @@ public abstract class AdvertiseCallback {
* Callback when advertising could not be started.
*
* @param errorCode Error code (see ADVERTISE_FAILED_* constants) for advertising start
* failures.
* failures.
*/
public void onStartFailure(int errorCode) {
}

View File

@@ -118,11 +118,12 @@ public final class AdvertiseData implements Parcelable {
return false;
}
AdvertiseData other = (AdvertiseData) obj;
return Objects.equals(mServiceUuids, other.mServiceUuids) &&
BluetoothLeUtils.equals(mManufacturerSpecificData, other.mManufacturerSpecificData) &&
BluetoothLeUtils.equals(mServiceData, other.mServiceData) &&
mIncludeDeviceName == other.mIncludeDeviceName &&
mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
return Objects.equals(mServiceUuids, other.mServiceUuids)
&& BluetoothLeUtils.equals(mManufacturerSpecificData,
other.mManufacturerSpecificData)
&& BluetoothLeUtils.equals(mServiceData, other.mServiceData)
&& mIncludeDeviceName == other.mIncludeDeviceName
&& mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
}
@Override
@@ -160,12 +161,12 @@ public final class AdvertiseData implements Parcelable {
public static final Parcelable.Creator<AdvertiseData> CREATOR =
new Creator<AdvertiseData>() {
@Override
@Override
public AdvertiseData[] newArray(int size) {
return new AdvertiseData[size];
}
@Override
@Override
public AdvertiseData createFromParcel(Parcel in) {
Builder builder = new Builder();
ArrayList<ParcelUuid> uuids = in.createTypedArrayList(ParcelUuid.CREATOR);
@@ -222,7 +223,7 @@ public final class AdvertiseData implements Parcelable {
* @param serviceDataUuid 16-bit UUID of the service the data is associated with
* @param serviceData Service data
* @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
* empty.
* empty.
*/
public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
if (serviceDataUuid == null || serviceData == null) {
@@ -242,8 +243,8 @@ public final class AdvertiseData implements Parcelable {
*
* @param manufacturerId Manufacturer ID assigned by Bluetooth SIG.
* @param manufacturerSpecificData Manufacturer specific data
* @throws IllegalArgumentException If the {@code manufacturerId} is negative or
* {@code manufacturerSpecificData} is null.
* @throws IllegalArgumentException If the {@code manufacturerId} is negative or {@code
* manufacturerSpecificData} is null.
*/
public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
if (manufacturerId < 0) {

View File

@@ -86,7 +86,7 @@ public final class AdvertiseSettings implements Parcelable {
private AdvertiseSettings(Parcel in) {
mAdvertiseMode = in.readInt();
mAdvertiseTxPowerLevel = in.readInt();
mAdvertiseConnectable = in.readInt() != 0 ? true : false;
mAdvertiseConnectable = in.readInt() != 0;
mAdvertiseTimeoutMillis = in.readInt();
}
@@ -121,9 +121,9 @@ public final class AdvertiseSettings implements Parcelable {
@Override
public String toString() {
return "Settings [mAdvertiseMode=" + mAdvertiseMode
+ ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
+ ", mAdvertiseConnectable=" + mAdvertiseConnectable
+ ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis + "]";
+ ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
+ ", mAdvertiseConnectable=" + mAdvertiseConnectable
+ ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis + "]";
}
@Override
@@ -141,12 +141,12 @@ public final class AdvertiseSettings implements Parcelable {
public static final Parcelable.Creator<AdvertiseSettings> CREATOR =
new Creator<AdvertiseSettings>() {
@Override
@Override
public AdvertiseSettings[] newArray(int size) {
return new AdvertiseSettings[size];
}
@Override
@Override
public AdvertiseSettings createFromParcel(Parcel in) {
return new AdvertiseSettings(in);
}
@@ -164,10 +164,10 @@ public final class AdvertiseSettings implements Parcelable {
/**
* Set advertise mode to control the advertising power and latency.
*
* @param advertiseMode Bluetooth LE Advertising mode, can only be one of
* {@link AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
* {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED}, or
* {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
* @param advertiseMode Bluetooth LE Advertising mode, can only be one of {@link
* AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
* {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED},
* or {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
* @throws IllegalArgumentException If the advertiseMode is invalid.
*/
public Builder setAdvertiseMode(int advertiseMode) {
@@ -183,10 +183,10 @@ public final class AdvertiseSettings implements Parcelable {
* Set advertise TX power level to control the transmission power level for the advertising.
*
* @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of
* {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW},
* {@link AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
* {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM} or
* {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
* {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW}, {@link
* AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
* {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM}
* or {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
* @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
*/
public Builder setTxPowerLevel(int txPowerLevel) {
@@ -201,8 +201,8 @@ public final class AdvertiseSettings implements Parcelable {
/**
* Set whether the advertisement type should be connectable or non-connectable.
*
* @param connectable Controls whether the advertisment type will be connectable (true)
* or non-connectable (false).
* @param connectable Controls whether the advertisment type will be connectable (true) or
* non-connectable (false).
*/
public Builder setConnectable(boolean connectable) {
mConnectable = connectable;
@@ -211,14 +211,15 @@ public final class AdvertiseSettings implements Parcelable {
/**
* Limit advertising to a given amount of time.
* @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds.
* A value of 0 will disable the time limit.
*
* @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds. A value
* of 0 will disable the time limit.
* @throws IllegalArgumentException If the provided timeout is over 180000 ms.
*/
public Builder setTimeout(int timeoutMillis) {
if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
throw new IllegalArgumentException("timeoutMillis invalid (must be 0-"
+ LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
+ LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
}
mTimeoutMillis = timeoutMillis;
return this;

View File

@@ -19,7 +19,6 @@ package android.bluetooth.le;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
import android.bluetooth.le.IAdvertisingSetCallback;
import android.os.RemoteException;
import android.util.Log;
@@ -37,23 +36,23 @@ import android.util.Log;
public final class AdvertisingSet {
private static final String TAG = "AdvertisingSet";
private final IBluetoothGatt gatt;
private int advertiserId;
private final IBluetoothGatt mGatt;
private int mAdvertiserId;
/* package */ AdvertisingSet(int advertiserId,
IBluetoothManager bluetoothManager) {
this.advertiserId = advertiserId;
IBluetoothManager bluetoothManager) {
mAdvertiserId = advertiserId;
try {
this.gatt = bluetoothManager.getBluetoothGatt();
mGatt = bluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
throw new IllegalStateException("Failed to get Bluetooth");
Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
throw new IllegalStateException("Failed to get Bluetooth");
}
}
/* package */ void setAdvertiserId(int advertiserId) {
this.advertiserId = advertiserId;
mAdvertiserId = advertiserId;
}
/**
@@ -63,18 +62,17 @@ public final class AdvertisingSet {
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
*
* @param enable whether the advertising should be enabled (true), or disabled (false)
* @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
* 65535 (655,350 ms)
* @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
* (655,350 ms)
* @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
* controller shall attempt to send prior to terminating the extended
* advertising, even if the duration has not expired. Valid range is
* from 1 to 255.
* controller shall attempt to send prior to terminating the extended advertising, even if the
* duration has not expired. Valid range is from 1 to 255.
*/
public void enableAdvertising(boolean enable, int duration,
int maxExtendedAdvertisingEvents) {
try {
gatt.enableAdvertisingSet(this.advertiserId, enable, duration,
maxExtendedAdvertisingEvents);
mGatt.enableAdvertisingSet(mAdvertiserId, enable, duration,
maxExtendedAdvertisingEvents);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -87,15 +85,14 @@ public final class AdvertisingSet {
* <p>
* Advertising data must be empty if non-legacy scannable advertising is used.
*
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
* advertisement is connectable, three bytes will be added for flags. If the
* update takes place when the advertising set is enabled, the data can be
* maximum 251 bytes long.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
* three bytes will be added for flags. If the update takes place when the advertising set is
* enabled, the data can be maximum 251 bytes long.
*/
public void setAdvertisingData(AdvertiseData advertiseData) {
try {
gatt.setAdvertisingData(this.advertiserId, advertiseData);
mGatt.setAdvertisingData(mAdvertiserId, advertiseData);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -107,13 +104,12 @@ public final class AdvertisingSet {
* is delivered through {@code callback.onScanResponseDataSet()}.
*
* @param scanResponse Scan response associated with the advertisement data. Size must not
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
* update takes place when the advertising set is enabled, the data can be
* maximum 251 bytes long.
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place
* when the advertising set is enabled, the data can be maximum 251 bytes long.
*/
public void setScanResponseData(AdvertiseData scanResponse) {
try {
gatt.setScanResponseData(this.advertiserId, scanResponse);
mGatt.setScanResponseData(mAdvertiserId, scanResponse);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -128,7 +124,7 @@ public final class AdvertisingSet {
*/
public void setAdvertisingParameters(AdvertisingSetParameters parameters) {
try {
gatt.setAdvertisingParameters(this.advertiserId, parameters);
mGatt.setAdvertisingParameters(mAdvertiserId, parameters);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -141,7 +137,7 @@ public final class AdvertisingSet {
*/
public void setPeriodicAdvertisingParameters(PeriodicAdvertisingParameters parameters) {
try {
gatt.setPeriodicAdvertisingParameters(this.advertiserId, parameters);
mGatt.setPeriodicAdvertisingParameters(mAdvertiserId, parameters);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -153,14 +149,13 @@ public final class AdvertisingSet {
* immediately, the operation status is delivered through
* {@code callback.onPeriodicAdvertisingDataSet()}.
*
* @param periodicData Periodic advertising data. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
* update takes place when the periodic advertising is enabled for this set,
* the data can be maximum 251 bytes long.
* @param periodicData Periodic advertising data. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place when the
* periodic advertising is enabled for this set, the data can be maximum 251 bytes long.
*/
public void setPeriodicAdvertisingData(AdvertiseData periodicData) {
try {
gatt.setPeriodicAdvertisingData(this.advertiserId, periodicData);
mGatt.setPeriodicAdvertisingData(mAdvertiserId, periodicData);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -170,11 +165,12 @@ public final class AdvertisingSet {
* Used to enable/disable periodic advertising. This method returns immediately, the operation
* status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
*
* @param enable whether the periodic advertising should be enabled (true), or disabled (false).
* @param enable whether the periodic advertising should be enabled (true), or disabled
* (false).
*/
public void setPeriodicAdvertisingEnabled(boolean enable) {
try {
gatt.setPeriodicAdvertisingEnable(this.advertiserId, enable);
mGatt.setPeriodicAdvertisingEnable(mAdvertiserId, enable);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -186,11 +182,12 @@ public final class AdvertisingSet {
* should ever use it.
*
* This method requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission.
*
* @hide
*/
public void getOwnAddress(){
public void getOwnAddress() {
try {
gatt.getOwnAddress(this.advertiserId);
mGatt.getOwnAddress(mAdvertiserId);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -201,7 +198,7 @@ public final class AdvertisingSet {
*
* @hide
*/
public int getAdvertiserId(){
return advertiserId;
public int getAdvertiserId() {
return mAdvertiserId;
}
}
}

View File

@@ -16,8 +16,6 @@
package android.bluetooth.le;
import android.bluetooth.BluetoothDevice;
/**
* Bluetooth LE advertising set callbacks, used to deliver advertising operation
* status.
@@ -65,7 +63,8 @@ public abstract class AdvertisingSetCallback {
* @param txPower tx power that will be used for this set.
* @param status Status of the operation.
*/
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {}
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
}
/**
* Callback triggered in response to {@link BluetoothLeAdvertiser#stopAdvertisingSet}
@@ -73,16 +72,19 @@ public abstract class AdvertisingSetCallback {
*
* @param advertisingSet The advertising set.
*/
public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {}
public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
}
/**
* Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet} indicating
* result of the operation. If status is ADVERTISE_SUCCESS, then advertising set is advertising.
* Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet}
* indicating result of the operation. If status is ADVERTISE_SUCCESS, then advertising set is
* advertising.
*
* @param advertisingSet The advertising set.
* @param status Status of the operation.
*/
public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {}
public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {
}
/**
* Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
@@ -91,7 +93,8 @@ public abstract class AdvertisingSetCallback {
* @param advertisingSet The advertising set.
* @param status Status of the operation.
*/
public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {}
public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {
}
/**
* Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
@@ -100,7 +103,8 @@ public abstract class AdvertisingSetCallback {
* @param advertisingSet The advertising set.
* @param status Status of the operation.
*/
public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {}
public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {
}
/**
* Callback triggered in response to {@link AdvertisingSet#setAdvertisingParameters}
@@ -111,7 +115,8 @@ public abstract class AdvertisingSetCallback {
* @param status Status of the operation.
*/
public void onAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
int txPower, int status) {}
int txPower, int status) {
}
/**
* Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingParameters}
@@ -120,9 +125,8 @@ public abstract class AdvertisingSetCallback {
* @param advertisingSet The advertising set.
* @param status Status of the operation.
*/
public void
onPeriodicAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
int status) {}
public void onPeriodicAdvertisingParametersUpdated(AdvertisingSet advertisingSet, int status) {
}
/**
* Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingData}
@@ -132,7 +136,8 @@ public abstract class AdvertisingSetCallback {
* @param status Status of the operation.
*/
public void onPeriodicAdvertisingDataSet(AdvertisingSet advertisingSet,
int status) {}
int status) {
}
/**
* Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingEnabled}
@@ -142,7 +147,8 @@ public abstract class AdvertisingSetCallback {
* @param status Status of the operation.
*/
public void onPeriodicAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable,
int status) {}
int status) {
}
/**
* Callback triggered in response to {@link AdvertisingSet#getOwnAddress()}
@@ -153,5 +159,6 @@ public abstract class AdvertisingSetCallback {
* @param address advertising set bluetooth address.
* @hide
*/
public void onOwnAddressRead(AdvertisingSet advertisingSet, int addressType, String address) {}
}
public void onOwnAddressRead(AdvertisingSet advertisingSet, int addressType, String address) {
}
}

View File

@@ -31,9 +31,9 @@ import android.os.Parcelable;
public final class AdvertisingSetParameters implements Parcelable {
/**
* Advertise on low frequency, around every 1000ms. This is the default and
* preferred advertising mode as it consumes the least power.
*/
* Advertise on low frequency, around every 1000ms. This is the default and
* preferred advertising mode as it consumes the least power.
*/
public static final int INTERVAL_HIGH = 1600;
/**
@@ -97,156 +97,174 @@ public final class AdvertisingSetParameters implements Parcelable {
*/
private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
private final boolean isLegacy;
private final boolean isAnonymous;
private final boolean includeTxPower;
private final int primaryPhy;
private final int secondaryPhy;
private final boolean connectable;
private final boolean scannable;
private final int interval;
private final int txPowerLevel;
private final boolean mIsLegacy;
private final boolean mIsAnonymous;
private final boolean mIncludeTxPower;
private final int mPrimaryPhy;
private final int mSecondaryPhy;
private final boolean mConnectable;
private final boolean mScannable;
private final int mInterval;
private final int mTxPowerLevel;
private AdvertisingSetParameters(boolean connectable, boolean scannable, boolean isLegacy,
boolean isAnonymous, boolean includeTxPower,
int primaryPhy, int secondaryPhy,
int interval, int txPowerLevel) {
this.connectable = connectable;
this.scannable = scannable;
this.isLegacy = isLegacy;
this.isAnonymous = isAnonymous;
this.includeTxPower = includeTxPower;
this.primaryPhy = primaryPhy;
this.secondaryPhy = secondaryPhy;
this.interval = interval;
this.txPowerLevel = txPowerLevel;
boolean isAnonymous, boolean includeTxPower,
int primaryPhy, int secondaryPhy,
int interval, int txPowerLevel) {
mConnectable = connectable;
mScannable = scannable;
mIsLegacy = isLegacy;
mIsAnonymous = isAnonymous;
mIncludeTxPower = includeTxPower;
mPrimaryPhy = primaryPhy;
mSecondaryPhy = secondaryPhy;
mInterval = interval;
mTxPowerLevel = txPowerLevel;
}
private AdvertisingSetParameters(Parcel in) {
connectable = in.readInt() != 0 ? true : false;
scannable = in.readInt() != 0 ? true : false;
isLegacy = in.readInt() != 0 ? true : false;
isAnonymous = in.readInt() != 0 ? true : false;
includeTxPower = in.readInt() != 0 ? true : false;
primaryPhy = in.readInt();
secondaryPhy = in.readInt();
interval = in.readInt();
txPowerLevel = in.readInt();
mConnectable = in.readInt() != 0;
mScannable = in.readInt() != 0;
mIsLegacy = in.readInt() != 0;
mIsAnonymous = in.readInt() != 0;
mIncludeTxPower = in.readInt() != 0;
mPrimaryPhy = in.readInt();
mSecondaryPhy = in.readInt();
mInterval = in.readInt();
mTxPowerLevel = in.readInt();
}
/**
* Returns whether the advertisement will be connectable.
*/
public boolean isConnectable() { return connectable; }
public boolean isConnectable() {
return mConnectable;
}
/**
* Returns whether the advertisement will be scannable.
*/
public boolean isScannable() { return scannable; }
public boolean isScannable() {
return mScannable;
}
/**
* Returns whether the legacy advertisement will be used.
*/
public boolean isLegacy() { return isLegacy; }
public boolean isLegacy() {
return mIsLegacy;
}
/**
* Returns whether the advertisement will be anonymous.
*/
public boolean isAnonymous() { return isAnonymous; }
public boolean isAnonymous() {
return mIsAnonymous;
}
/**
* Returns whether the TX Power will be included.
*/
public boolean includeTxPower() { return includeTxPower; }
public boolean includeTxPower() {
return mIncludeTxPower;
}
/**
* Returns the primary advertising phy.
*/
public int getPrimaryPhy() { return primaryPhy; }
public int getPrimaryPhy() {
return mPrimaryPhy;
}
/**
* Returns the secondary advertising phy.
*/
public int getSecondaryPhy() { return secondaryPhy; }
public int getSecondaryPhy() {
return mSecondaryPhy;
}
/**
* Returns the advertising interval.
*/
public int getInterval() { return interval; }
public int getInterval() {
return mInterval;
}
/**
* Returns the TX power level for advertising.
*/
public int getTxPowerLevel() { return txPowerLevel; }
public int getTxPowerLevel() {
return mTxPowerLevel;
}
@Override
public String toString() {
return "AdvertisingSetParameters [connectable=" + connectable
+ ", isLegacy=" + isLegacy
+ ", isAnonymous=" + isAnonymous
+ ", includeTxPower=" + includeTxPower
+ ", primaryPhy=" + primaryPhy
+ ", secondaryPhy=" + secondaryPhy
+ ", interval=" + interval
+ ", txPowerLevel=" + txPowerLevel + "]";
return "AdvertisingSetParameters [connectable=" + mConnectable
+ ", isLegacy=" + mIsLegacy
+ ", isAnonymous=" + mIsAnonymous
+ ", includeTxPower=" + mIncludeTxPower
+ ", primaryPhy=" + mPrimaryPhy
+ ", secondaryPhy=" + mSecondaryPhy
+ ", interval=" + mInterval
+ ", txPowerLevel=" + mTxPowerLevel + "]";
}
@Override
public int describeContents() {
return 0;
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(connectable ? 1 : 0);
dest.writeInt(scannable ? 1 : 0);
dest.writeInt(isLegacy ? 1 : 0);
dest.writeInt(isAnonymous ? 1 : 0);
dest.writeInt(includeTxPower ? 1 : 0);
dest.writeInt(primaryPhy);
dest.writeInt(secondaryPhy);
dest.writeInt(interval);
dest.writeInt(txPowerLevel);
dest.writeInt(mConnectable ? 1 : 0);
dest.writeInt(mScannable ? 1 : 0);
dest.writeInt(mIsLegacy ? 1 : 0);
dest.writeInt(mIsAnonymous ? 1 : 0);
dest.writeInt(mIncludeTxPower ? 1 : 0);
dest.writeInt(mPrimaryPhy);
dest.writeInt(mSecondaryPhy);
dest.writeInt(mInterval);
dest.writeInt(mTxPowerLevel);
}
public static final Parcelable.Creator<AdvertisingSetParameters> CREATOR =
new Creator<AdvertisingSetParameters>() {
@Override
public AdvertisingSetParameters[] newArray(int size) {
return new AdvertisingSetParameters[size];
}
new Creator<AdvertisingSetParameters>() {
@Override
public AdvertisingSetParameters[] newArray(int size) {
return new AdvertisingSetParameters[size];
}
@Override
public AdvertisingSetParameters createFromParcel(Parcel in) {
return new AdvertisingSetParameters(in);
}
};
@Override
public AdvertisingSetParameters createFromParcel(Parcel in) {
return new AdvertisingSetParameters(in);
}
};
/**
* Builder class for {@link AdvertisingSetParameters}.
*/
public static final class Builder {
private boolean connectable = false;
private boolean scannable = false;
private boolean isLegacy = false;
private boolean isAnonymous = false;
private boolean includeTxPower = false;
private int primaryPhy = BluetoothDevice.PHY_LE_1M;
private int secondaryPhy = BluetoothDevice.PHY_LE_1M;
private int interval = INTERVAL_LOW;
private int txPowerLevel = TX_POWER_MEDIUM;
private boolean mConnectable = false;
private boolean mScannable = false;
private boolean mIsLegacy = false;
private boolean mIsAnonymous = false;
private boolean mIncludeTxPower = false;
private int mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
private int mSecondaryPhy = BluetoothDevice.PHY_LE_1M;
private int mInterval = INTERVAL_LOW;
private int mTxPowerLevel = TX_POWER_MEDIUM;
/**
* Set whether the advertisement type should be connectable or
* non-connectable.
* Legacy advertisements can be both connectable and scannable. Non-legacy
* advertisements can be only scannable or only connectable.
* @param connectable Controls whether the advertisement type will be
* connectable (true) or non-connectable (false).
*
* @param connectable Controls whether the advertisement type will be connectable (true) or
* non-connectable (false).
*/
public Builder setConnectable(boolean connectable) {
this.connectable = connectable;
mConnectable = connectable;
return this;
}
@@ -254,11 +272,12 @@ public final class AdvertisingSetParameters implements Parcelable {
* Set whether the advertisement type should be scannable.
* Legacy advertisements can be both connectable and scannable. Non-legacy
* advertisements can be only scannable or only connectable.
* @param scannable Controls whether the advertisement type will be
* scannable (true) or non-scannable (false).
*
* @param scannable Controls whether the advertisement type will be scannable (true) or
* non-scannable (false).
*/
public Builder setScannable(boolean scannable) {
this.scannable = scannable;
mScannable = scannable;
return this;
}
@@ -269,7 +288,7 @@ public final class AdvertisingSetParameters implements Parcelable {
* @param isLegacy whether legacy advertising mode should be used.
*/
public Builder setLegacyMode(boolean isLegacy) {
this.isLegacy = isLegacy;
mIsLegacy = isLegacy;
return this;
}
@@ -282,7 +301,7 @@ public final class AdvertisingSetParameters implements Parcelable {
* @param isAnonymous whether anonymous advertising should be used.
*/
public Builder setAnonymous(boolean isAnonymous) {
this.isAnonymous = isAnonymous;
mIsAnonymous = isAnonymous;
return this;
}
@@ -291,11 +310,10 @@ public final class AdvertisingSetParameters implements Parcelable {
*
* This is used only if legacy mode is not used.
*
* @param includeTxPower whether TX power should be included in extended
* header
* @param includeTxPower whether TX power should be included in extended header
*/
public Builder setIncludeTxPower(boolean includeTxPower) {
this.includeTxPower = includeTxPower;
mIncludeTxPower = includeTxPower;
return this;
}
@@ -306,17 +324,17 @@ public final class AdvertisingSetParameters implements Parcelable {
*
* Use {@link BluetoothAdapter#isLeCodedPhySupported} to determine if LE Coded PHY is
* supported on this device.
* @param primaryPhy Primary advertising physical channel, can only be
* {@link BluetoothDevice#PHY_LE_1M} or
* {@link BluetoothDevice#PHY_LE_CODED}.
*
* @param primaryPhy Primary advertising physical channel, can only be {@link
* BluetoothDevice#PHY_LE_1M} or {@link BluetoothDevice#PHY_LE_CODED}.
* @throws IllegalArgumentException If the primaryPhy is invalid.
*/
public Builder setPrimaryPhy(int primaryPhy) {
if (primaryPhy != BluetoothDevice.PHY_LE_1M &&
primaryPhy != BluetoothDevice.PHY_LE_CODED) {
throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
if (primaryPhy != BluetoothDevice.PHY_LE_1M
&& primaryPhy != BluetoothDevice.PHY_LE_CODED) {
throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
}
this.primaryPhy = primaryPhy;
mPrimaryPhy = primaryPhy;
return this;
}
@@ -329,95 +347,91 @@ public final class AdvertisingSetParameters implements Parcelable {
* {@link BluetoothAdapter#isLe2MPhySupported} to determine if LE Coded PHY or 2M PHY is
* supported on this device.
*
* @param secondaryPhy Secondary advertising physical channel, can only be
* one of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M} or
* {@link BluetoothDevice#PHY_LE_CODED}.
* @param secondaryPhy Secondary advertising physical channel, can only be one of {@link
* BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M} or {@link
* BluetoothDevice#PHY_LE_CODED}.
* @throws IllegalArgumentException If the secondaryPhy is invalid.
*/
public Builder setSecondaryPhy(int secondaryPhy) {
if (secondaryPhy != BluetoothDevice.PHY_LE_1M &&
secondaryPhy != BluetoothDevice.PHY_LE_2M &&
secondaryPhy != BluetoothDevice.PHY_LE_CODED) {
throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
if (secondaryPhy != BluetoothDevice.PHY_LE_1M
&& secondaryPhy != BluetoothDevice.PHY_LE_2M
&& secondaryPhy != BluetoothDevice.PHY_LE_CODED) {
throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
}
this.secondaryPhy = secondaryPhy;
mSecondaryPhy = secondaryPhy;
return this;
}
/**
* Set advertising interval.
*
* @param interval Bluetooth LE Advertising interval, in 0.625ms unit. Valid
* range is from 160 (100ms) to 16777215 (10,485.759375 s).
* Recommended values are:
* {@link AdvertisingSetParameters#INTERVAL_LOW},
* {@link AdvertisingSetParameters#INTERVAL_MEDIUM}, or
* {@link AdvertisingSetParameters#INTERVAL_HIGH}.
* @param interval Bluetooth LE Advertising interval, in 0.625ms unit. Valid range is from
* 160 (100ms) to 16777215 (10,485.759375 s). Recommended values are: {@link
* AdvertisingSetParameters#INTERVAL_LOW}, {@link AdvertisingSetParameters#INTERVAL_MEDIUM},
* or {@link AdvertisingSetParameters#INTERVAL_HIGH}.
* @throws IllegalArgumentException If the interval is invalid.
*/
public Builder setInterval(int interval) {
if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
throw new IllegalArgumentException("unknown interval " + interval);
throw new IllegalArgumentException("unknown interval " + interval);
}
this.interval = interval;
mInterval = interval;
return this;
}
/**
* Set the transmission power level for the advertising.
* @param txPowerLevel Transmission power of Bluetooth LE Advertising, in
* dBm. The valid range is [-127, 1] Recommended values are:
* {@link AdvertisingSetParameters#TX_POWER_ULTRA_LOW},
* {@link AdvertisingSetParameters#TX_POWER_LOW},
* {@link AdvertisingSetParameters#TX_POWER_MEDIUM}, or
* {@link AdvertisingSetParameters#TX_POWER_HIGH}.
*
* @param txPowerLevel Transmission power of Bluetooth LE Advertising, in dBm. The valid
* range is [-127, 1] Recommended values are:
* {@link AdvertisingSetParameters#TX_POWER_ULTRA_LOW},
* {@link AdvertisingSetParameters#TX_POWER_LOW},
* {@link AdvertisingSetParameters#TX_POWER_MEDIUM},
* or {@link AdvertisingSetParameters#TX_POWER_HIGH}.
* @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
*/
public Builder setTxPowerLevel(int txPowerLevel) {
if (txPowerLevel < TX_POWER_MIN || txPowerLevel > TX_POWER_MAX) {
throw new IllegalArgumentException("unknown txPowerLevel " +
txPowerLevel);
throw new IllegalArgumentException("unknown txPowerLevel " + txPowerLevel);
}
this.txPowerLevel = txPowerLevel;
mTxPowerLevel = txPowerLevel;
return this;
}
/**
* Build the {@link AdvertisingSetParameters} object.
*
* @throws IllegalStateException if invalid combination of parameters is used.
*/
public AdvertisingSetParameters build() {
if (isLegacy) {
if (isAnonymous) {
if (mIsLegacy) {
if (mIsAnonymous) {
throw new IllegalArgumentException("Legacy advertising can't be anonymous");
}
if (connectable == true && scannable == false) {
if (mConnectable && !mScannable) {
throw new IllegalStateException(
"Legacy advertisement can't be connectable and non-scannable");
"Legacy advertisement can't be connectable and non-scannable");
}
if (includeTxPower) {
if (mIncludeTxPower) {
throw new IllegalStateException(
"Legacy advertising can't include TX power level in header");
"Legacy advertising can't include TX power level in header");
}
} else {
if (connectable && scannable) {
if (mConnectable && mScannable) {
throw new IllegalStateException(
"Advertising can't be both connectable and scannable");
"Advertising can't be both connectable and scannable");
}
if (isAnonymous && connectable) {
if (mIsAnonymous && mConnectable) {
throw new IllegalStateException(
"Advertising can't be both connectable and anonymous");
"Advertising can't be both connectable and anonymous");
}
}
return new AdvertisingSetParameters(connectable, scannable, isLegacy, isAnonymous,
includeTxPower, primaryPhy,
secondaryPhy, interval, txPowerLevel);
return new AdvertisingSetParameters(mConnectable, mScannable, mIsLegacy, mIsAnonymous,
mIncludeTxPower, mPrimaryPhy, mSecondaryPhy, mInterval, mTxPowerLevel);
}
}
}
}

View File

@@ -18,7 +18,6 @@ package android.bluetooth.le;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
@@ -31,7 +30,6 @@ import android.util.Log;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* This class provides a way to perform Bluetooth LE advertise operations, such as starting and
@@ -117,8 +115,8 @@ public final class BluetoothLeAdvertiser {
throw new IllegalArgumentException("callback cannot be null");
}
boolean isConnectable = settings.isConnectable();
if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES ||
totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES
|| totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
return;
}
@@ -152,13 +150,13 @@ public final class BluetoothLeAdvertiser {
int duration = 0;
int timeoutMillis = settings.getTimeout();
if (timeoutMillis > 0) {
duration = (timeoutMillis < 10) ? 1 : timeoutMillis/10;
duration = (timeoutMillis < 10) ? 1 : timeoutMillis / 10;
}
AdvertisingSetCallback wrapped = wrapOldCallback(callback, settings);
mLegacyAdvertisers.put(callback, wrapped);
startAdvertisingSet(parameters.build(), advertiseData, scanResponse, null, null,
duration, 0, wrapped);
duration, 0, wrapped);
}
}
@@ -166,7 +164,7 @@ public final class BluetoothLeAdvertiser {
return new AdvertisingSetCallback() {
@Override
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower,
int status) {
int status) {
if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
postStartFailure(callback, status);
return;
@@ -178,10 +176,10 @@ public final class BluetoothLeAdvertiser {
/* Legacy advertiser is disabled on timeout */
@Override
public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enabled,
int status) {
if (enabled == true) {
Log.e(TAG, "Legacy advertiser should be only disabled on timeout," +
" but was enabled!");
int status) {
if (enabled) {
Log.e(TAG, "Legacy advertiser should be only disabled on timeout,"
+ " but was enabled!");
return;
}
@@ -218,28 +216,28 @@ public final class BluetoothLeAdvertiser {
* method returns immediately, the operation status is delivered through
* {@code callback.onAdvertisingSetStarted()}.
* <p>
*
* @param parameters advertising set parameters.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
* advertisement is connectable, three bytes will be added for flags.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
* three bytes will be added for flags.
* @param scanResponse Scan response associated with the advertisement data. Size must not
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
* not be started.
* @param periodicData Periodic advertising data. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* not be started.
* @param periodicData Periodic advertising data. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* @param callback Callback for advertising set.
* @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
* size, or unsupported advertising PHY is selected, or when attempt to use
* Periodic Advertising feature is made when it's not supported by the
* controller.
* size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
* feature is made when it's not supported by the controller.
*/
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, AdvertisingSetCallback callback) {
startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
periodicData, 0, 0, callback, new Handler(Looper.getMainLooper()));
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, AdvertisingSetCallback callback) {
startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
periodicData, 0, 0, callback, new Handler(Looper.getMainLooper()));
}
/**
@@ -247,30 +245,30 @@ public final class BluetoothLeAdvertiser {
* method returns immediately, the operation status is delivered through
* {@code callback.onAdvertisingSetStarted()}.
* <p>
*
* @param parameters advertising set parameters.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
* advertisement is connectable, three bytes will be added for flags.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
* three bytes will be added for flags.
* @param scanResponse Scan response associated with the advertisement data. Size must not
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
* not be started.
* @param periodicData Periodic advertising data. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* not be started.
* @param periodicData Periodic advertising data. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* @param callback Callback for advertising set.
* @param handler thread upon which the callbacks will be invoked.
* @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
* size, or unsupported advertising PHY is selected, or when attempt to use
* Periodic Advertising feature is made when it's not supported by the
* controller.
* size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
* feature is made when it's not supported by the controller.
*/
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, AdvertisingSetCallback callback,
Handler handler) {
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, AdvertisingSetCallback callback,
Handler handler) {
startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
periodicData, 0, 0, callback, handler);
periodicData, 0, 0, callback, handler);
}
/**
@@ -278,37 +276,36 @@ public final class BluetoothLeAdvertiser {
* method returns immediately, the operation status is delivered through
* {@code callback.onAdvertisingSetStarted()}.
* <p>
*
* @param parameters advertising set parameters.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
* advertisement is connectable, three bytes will be added for flags.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
* three bytes will be added for flags.
* @param scanResponse Scan response associated with the advertisement data. Size must not
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
* not be started.
* @param periodicData Periodic advertising data. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
* 65535 (655,350 ms). 0 means advertising should continue until stopped.
* not be started.
* @param periodicData Periodic advertising data. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
* @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
* (655,350 ms). 0 means advertising should continue until stopped.
* @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
* controller shall attempt to send prior to terminating the extended
* advertising, even if the duration has not expired. Valid range is
* from 1 to 255. 0 means no maximum.
* controller shall attempt to send prior to terminating the extended advertising, even if the
* duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
* @param callback Callback for advertising set.
* @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
* size, or unsupported advertising PHY is selected, or when attempt to use
* Periodic Advertising feature is made when it's not supported by the
* controller.
* size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
* feature is made when it's not supported by the controller.
*/
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, int duration,
int maxExtendedAdvertisingEvents,
AdvertisingSetCallback callback) {
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, int duration,
int maxExtendedAdvertisingEvents,
AdvertisingSetCallback callback) {
startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
periodicData, duration, maxExtendedAdvertisingEvents, callback,
new Handler(Looper.getMainLooper()));
periodicData, duration, maxExtendedAdvertisingEvents, callback,
new Handler(Looper.getMainLooper()));
}
/**
@@ -316,39 +313,39 @@ public final class BluetoothLeAdvertiser {
* method returns immediately, the operation status is delivered through
* {@code callback.onAdvertisingSetStarted()}.
* <p>
*
* @param parameters Advertising set parameters.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
* advertisement is connectable, three bytes will be added for flags.
* @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
* three bytes will be added for flags.
* @param scanResponse Scan response associated with the advertisement data. Size must not
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
* exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
* @param periodicParameters Periodic advertisng parameters. If null, periodic advertising will
* not be started.
* @param periodicData Periodic advertising data. Size must not exceed
* {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
* @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
* 65535 (655,350 ms). 0 means advertising should continue until stopped.
* not be started.
* @param periodicData Periodic advertising data. Size must not exceed {@link
* BluetoothAdapter#getLeMaximumAdvertisingDataLength}
* @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
* (655,350 ms). 0 means advertising should continue until stopped.
* @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
* controller shall attempt to send prior to terminating the extended
* advertising, even if the duration has not expired. Valid range is
* from 1 to 255. 0 means no maximum.
* controller shall attempt to send prior to terminating the extended advertising, even if the
* duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
* @param callback Callback for advertising set.
* @param handler Thread upon which the callbacks will be invoked.
* @throws IllegalArgumentException When any of the data parameter exceed the maximum allowable
* size, or unsupported advertising PHY is selected, or when attempt to use
* Periodic Advertising feature is made when it's not supported by the
* controller, or when maxExtendedAdvertisingEvents is used on a controller
* that doesn't support the LE Extended Advertising
* size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
* feature is made when it's not supported by the controller, or when
* maxExtendedAdvertisingEvents is used on a controller that doesn't support the LE Extended
* Advertising
*/
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, int duration,
int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
Handler handler) {
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, int duration,
int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
Handler handler) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
throw new IllegalArgumentException("callback cannot be null");
}
boolean isConnectable = parameters.isConnectable();
@@ -370,7 +367,7 @@ public final class BluetoothLeAdvertiser {
}
if ((sphy == BluetoothDevice.PHY_LE_CODED && !supportCodedPhy)
|| (sphy == BluetoothDevice.PHY_LE_2M && !support2MPhy)) {
|| (sphy == BluetoothDevice.PHY_LE_2M && !support2MPhy)) {
throw new IllegalArgumentException("Unsupported secondary PHY selected");
}
@@ -390,20 +387,20 @@ public final class BluetoothLeAdvertiser {
boolean supportPeriodic = mBluetoothAdapter.isLePeriodicAdvertisingSupported();
if (periodicParameters != null && !supportPeriodic) {
throw new IllegalArgumentException(
"Controller does not support LE Periodic Advertising");
"Controller does not support LE Periodic Advertising");
}
}
if (maxExtendedAdvertisingEvents < 0 || maxExtendedAdvertisingEvents > 255) {
throw new IllegalArgumentException(
"maxExtendedAdvertisingEvents out of range: " + maxExtendedAdvertisingEvents);
"maxExtendedAdvertisingEvents out of range: " + maxExtendedAdvertisingEvents);
}
if (maxExtendedAdvertisingEvents != 0 &&
!mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
if (maxExtendedAdvertisingEvents != 0
&& !mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
throw new IllegalArgumentException(
"Can't use maxExtendedAdvertisingEvents with controller that don't support " +
"LE Extended Advertising");
"Can't use maxExtendedAdvertisingEvents with controller that don't support "
+ "LE Extended Advertising");
}
if (duration < 0 || duration > 65535) {
@@ -412,26 +409,28 @@ public final class BluetoothLeAdvertiser {
IBluetoothGatt gatt;
try {
gatt = mBluetoothManager.getBluetoothGatt();
gatt = mBluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
postStartSetFailure(handler, callback, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
return;
Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
postStartSetFailure(handler, callback,
AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
return;
}
IAdvertisingSetCallback wrapped = wrap(callback, handler);
if (mCallbackWrappers.putIfAbsent(callback, wrapped) != null) {
throw new IllegalArgumentException(
"callback instance already associated with advertising");
"callback instance already associated with advertising");
}
try {
gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
periodicData, duration, maxExtendedAdvertisingEvents, wrapped);
periodicData, duration, maxExtendedAdvertisingEvents, wrapped);
} catch (RemoteException e) {
Log.e(TAG, "Failed to start advertising set - ", e);
postStartSetFailure(handler, callback, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
return;
Log.e(TAG, "Failed to start advertising set - ", e);
postStartSetFailure(handler, callback,
AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
return;
}
}
@@ -441,7 +440,7 @@ public final class BluetoothLeAdvertiser {
*/
public void stopAdvertisingSet(AdvertisingSetCallback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
throw new IllegalArgumentException("callback cannot be null");
}
IAdvertisingSetCallback wrapped = mCallbackWrappers.remove(callback);
@@ -453,9 +452,9 @@ public final class BluetoothLeAdvertiser {
try {
gatt = mBluetoothManager.getBluetoothGatt();
gatt.stopAdvertisingSet(wrapped);
} catch (RemoteException e) {
} catch (RemoteException e) {
Log.e(TAG, "Failed to stop advertising - ", e);
}
}
}
/**
@@ -489,18 +488,16 @@ public final class BluetoothLeAdvertiser {
}
// 16 bit service uuids are grouped into one field when doing advertising.
if (num16BitUuids != 0) {
size += OVERHEAD_BYTES_PER_FIELD +
num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
size += OVERHEAD_BYTES_PER_FIELD + num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
}
// 32 bit service uuids are grouped into one field when doing advertising.
if (num32BitUuids != 0) {
size += OVERHEAD_BYTES_PER_FIELD +
num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
size += OVERHEAD_BYTES_PER_FIELD + num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
}
// 128 bit service uuids are grouped into one field when doing advertising.
if (num128BitUuids != 0) {
size += OVERHEAD_BYTES_PER_FIELD +
num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
size += OVERHEAD_BYTES_PER_FIELD
+ num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
}
}
for (ParcelUuid uuid : data.getServiceData().keySet()) {
@@ -509,8 +506,8 @@ public final class BluetoothLeAdvertiser {
+ byteLength(data.getServiceData().get(uuid));
}
for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH +
byteLength(data.getManufacturerSpecificData().valueAt(i));
size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH
+ byteLength(data.getManufacturerSpecificData().valueAt(i));
}
if (data.getIncludeTxPowerLevel()) {
size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
@@ -539,7 +536,7 @@ public final class BluetoothLeAdvertiser {
}
AdvertisingSet advertisingSet =
new AdvertisingSet(advertiserId, mBluetoothManager);
new AdvertisingSet(advertiserId, mBluetoothManager);
mAdvertisingSets.put(advertiserId, advertisingSet);
callback.onAdvertisingSetStarted(advertisingSet, txPower, status);
}
@@ -650,13 +647,13 @@ public final class BluetoothLeAdvertiser {
}
private void postStartSetFailure(Handler handler, final AdvertisingSetCallback callback,
final int error) {
final int error) {
handler.post(new Runnable() {
@Override
public void run() {
callback.onAdvertisingSetStarted(null, 0, error);
}
});
@Override
public void run() {
callback.onAdvertisingSetStarted(null, 0, error);
}
});
}
private void postStartFailure(final AdvertiseCallback callback, final int error) {

View File

@@ -62,8 +62,8 @@ public final class BluetoothLeScanner {
* error. In case of error, {@link #EXTRA_ERROR_CODE} will contain the error code and this
* extra will not be available.
*/
public static final String EXTRA_LIST_SCAN_RESULT
= "android.bluetooth.le.extra.LIST_SCAN_RESULT";
public static final String EXTRA_LIST_SCAN_RESULT =
"android.bluetooth.le.extra.LIST_SCAN_RESULT";
/**
* Optional extra indicating the error code, if any. The error code will be one of the
@@ -74,6 +74,7 @@ public final class BluetoothLeScanner {
/**
* Optional extra indicating the callback type, which will be one of
* CALLBACK_TYPE_* constants in {@link ScanSettings}.
*
* @see ScanCallback#onScanResult(int, ScanResult)
*/
public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
@@ -162,13 +163,13 @@ public final class BluetoothLeScanner {
* specify on behalf of which application(s) the work is being done.
*
* @param workSource {@link WorkSource} identifying the application(s) for which to blame for
* the scan.
* the scan.
* @param callback Callback used to deliver scan results.
* @hide
*/
@SystemApi
@RequiresPermission(allOf = {
Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS})
public void startScanFromSource(final WorkSource workSource, final ScanCallback callback) {
startScanFromSource(null, new ScanSettings.Builder().build(), workSource, callback);
}
@@ -180,22 +181,22 @@ public final class BluetoothLeScanner {
* @param filters {@link ScanFilter}s for finding exact BLE devices.
* @param settings Settings for the scan.
* @param workSource {@link WorkSource} identifying the application(s) for which to blame for
* the scan.
* the scan.
* @param callback Callback used to deliver scan results.
* @hide
*/
@SystemApi
@RequiresPermission(allOf = {
Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS})
public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
final WorkSource workSource, final ScanCallback callback) {
final WorkSource workSource, final ScanCallback callback) {
startScan(filters, settings, workSource, callback, null, null);
}
private int startScan(List<ScanFilter> filters, ScanSettings settings,
final WorkSource workSource, final ScanCallback callback,
final PendingIntent callbackIntent,
List<List<ResultStorageDescriptor>> resultStorages) {
final WorkSource workSource, final ScanCallback callback,
final PendingIntent callbackIntent,
List<List<ResultStorageDescriptor>> resultStorages) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
if (callback == null && callbackIntent == null) {
throw new IllegalArgumentException("callback is null");
@@ -219,11 +220,11 @@ public final class BluetoothLeScanner {
}
if (!isSettingsConfigAllowedForScan(settings)) {
return postCallbackErrorOrReturn(callback,
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
}
if (!isHardwareResourcesAvailableForScan(settings)) {
return postCallbackErrorOrReturn(callback,
ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
}
if (!isSettingsAndFilterComboAllowed(settings, filters)) {
return postCallbackErrorOrReturn(callback,
@@ -286,7 +287,7 @@ public final class BluetoothLeScanner {
* will be delivered through the {@code callback}.
*
* @param callback Callback of the Bluetooth LE Scan, it has to be the same instance as the one
* used to start scan.
* used to start scan.
*/
public void flushPendingScanResults(ScanCallback callback) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
@@ -419,8 +420,8 @@ public final class BluetoothLeScanner {
*/
@Override
public void onScannerRegistered(int status, int scannerId) {
Log.d(TAG, "onScannerRegistered() - status=" + status +
" scannerId=" + scannerId + " mScannerId=" + mScannerId);
Log.d(TAG, "onScannerRegistered() - status=" + status
+ " scannerId=" + scannerId + " mScannerId=" + mScannerId);
synchronized (this) {
if (status == BluetoothGatt.GATT_SUCCESS) {
try {
@@ -481,18 +482,18 @@ public final class BluetoothLeScanner {
@Override
public void onFoundOrLost(final boolean onFound, final ScanResult scanResult) {
if (VDBG) {
Log.d(TAG, "onFoundOrLost() - onFound = " + onFound +
" " + scanResult.toString());
Log.d(TAG, "onFoundOrLost() - onFound = " + onFound + " " + scanResult.toString());
}
// Check null in case the scan has been stopped
synchronized (this) {
if (mScannerId <= 0)
if (mScannerId <= 0) {
return;
}
}
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
@Override
public void run() {
if (onFound) {
mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_FIRST_MATCH,
@@ -511,8 +512,9 @@ public final class BluetoothLeScanner {
Log.d(TAG, "onScanManagerErrorCallback() - errorCode = " + errorCode);
}
synchronized (this) {
if (mScannerId <= 0)
if (mScannerId <= 0) {
return;
}
}
postCallbackError(mScanCallback, errorCode);
}
@@ -550,11 +552,11 @@ public final class BluetoothLeScanner {
}
private boolean isSettingsAndFilterComboAllowed(ScanSettings settings,
List <ScanFilter> filterList) {
List<ScanFilter> filterList) {
final int callbackType = settings.getCallbackType();
// If onlost/onfound is requested, a non-empty filter is expected
if ((callbackType & (ScanSettings.CALLBACK_TYPE_FIRST_MATCH
| ScanSettings.CALLBACK_TYPE_MATCH_LOST)) != 0) {
| ScanSettings.CALLBACK_TYPE_MATCH_LOST)) != 0) {
if (filterList == null) {
return false;
}
@@ -572,8 +574,8 @@ public final class BluetoothLeScanner {
if ((callbackType & ScanSettings.CALLBACK_TYPE_FIRST_MATCH) != 0
|| (callbackType & ScanSettings.CALLBACK_TYPE_MATCH_LOST) != 0) {
// For onlost/onfound, we required hw support be available
return (mBluetoothAdapter.isOffloadedFilteringSupported() &&
mBluetoothAdapter.isHardwareTrackingFiltersAvailable());
return (mBluetoothAdapter.isOffloadedFilteringSupported()
&& mBluetoothAdapter.isHardwareTrackingFiltersAvailable());
}
return true;
}

View File

@@ -92,8 +92,8 @@ public class BluetoothLeUtils {
// Keys are guaranteed in ascending order when indices are in ascending order.
for (int i = 0; i < array.size(); ++i) {
if (array.keyAt(i) != otherArray.keyAt(i) ||
!Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
if (array.keyAt(i) != otherArray.keyAt(i)
|| !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
return false;
}
}
@@ -128,11 +128,11 @@ public class BluetoothLeUtils {
/**
* Ensure Bluetooth is turned on.
*
* @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not
* {@link BluetoothAdapter#STATE_ON}.
* @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not {@link
* BluetoothAdapter#STATE_ON}.
*/
static void checkAdapterStateOn(BluetoothAdapter adapter) {
if (adapter == null || !adapter.isLeEnabled()) {//adapter.getState() != BluetoothAdapter.STATE_ON) {
if (adapter == null || !adapter.isLeEnabled()) {
throw new IllegalStateException("BT Adapter is not turned ON");
}
}

View File

@@ -22,8 +22,8 @@ import android.bluetooth.BluetoothDevice;
* Bluetooth LE periodic advertising callbacks, used to deliver periodic
* advertising operation status.
*
* @see PeriodicAdvertisingManager#createSync
* @hide
* @see PeriodicAdvertisingManager#createSync
*/
public abstract class PeriodicAdvertisingCallback {
@@ -40,7 +40,7 @@ public abstract class PeriodicAdvertisingCallback {
public static final int SYNC_NO_RESPONSE = 1;
/**
* Sync failed to be established because controller can't support more syncs.
* Sync failed to be established because controller can't support more syncs.
*/
public static final int SYNC_NO_RESOURCES = 2;
@@ -51,28 +51,31 @@ public abstract class PeriodicAdvertisingCallback {
* @param syncHandle handle used to identify this synchronization.
* @param device remote device.
* @param advertisingSid synchronized advertising set id.
* @param skip The number of periodic advertising packets that can be skipped
* after a successful receive in force. @see PeriodicAdvertisingManager#createSync
* @param timeout Synchronization timeout for the periodic advertising in force. One
* unit is 10ms. @see PeriodicAdvertisingManager#createSync
* @param skip The number of periodic advertising packets that can be skipped after a successful
* receive in force. @see PeriodicAdvertisingManager#createSync
* @param timeout Synchronization timeout for the periodic advertising in force. One unit is
* 10ms. @see PeriodicAdvertisingManager#createSync
* @param timeout
* @param status operation status.
*/
public void onSyncEstablished(int syncHandle, BluetoothDevice device,
int advertisingSid, int skip, int timeout,
int status) {}
int advertisingSid, int skip, int timeout,
int status) {
}
/**
* Callback when periodic advertising report is received.
*
* @param report periodic advertising report.
*/
public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {}
public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
}
/**
* Callback when periodic advertising synchronization was lost.
*
* @param syncHandle handle used to identify this synchronization.
*/
public void onSyncLost(int syncHandle) {}
public void onSyncLost(int syncHandle) {
}
}

View File

@@ -24,6 +24,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import java.util.IdentityHashMap;
import java.util.Map;
@@ -37,202 +38,207 @@ import java.util.Map;
* <p>
* <b>Note:</b> Most of the methods here require
* {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @hide
*/
public final class PeriodicAdvertisingManager {
private static final String TAG = "PeriodicAdvertisingManager";
private static final String TAG = "PeriodicAdvertisingManager";
private static final int SKIP_MIN = 0;
private static final int SKIP_MAX = 499;
private static final int TIMEOUT_MIN = 10;
private static final int TIMEOUT_MAX = 16384;
private static final int SKIP_MIN = 0;
private static final int SKIP_MAX = 499;
private static final int TIMEOUT_MIN = 10;
private static final int TIMEOUT_MAX = 16384;
private static final int SYNC_STARTING = -1;
private static final int SYNC_STARTING = -1;
private final IBluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private final IBluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
/* maps callback, to callback wrapper and sync handle */
Map<PeriodicAdvertisingCallback,
IPeriodicAdvertisingCallback /* callbackWrapper */> callbackWrappers;
/* maps callback, to callback wrapper and sync handle */
Map<PeriodicAdvertisingCallback,
IPeriodicAdvertisingCallback /* callbackWrapper */> mCallbackWrappers;
/**
* Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
*
* @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
* @hide
*/
public PeriodicAdvertisingManager(IBluetoothManager bluetoothManager) {
mBluetoothManager = bluetoothManager;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
callbackWrappers = new IdentityHashMap<>();
}
/**
* Synchronize with periodic advertising pointed to by the {@code scanResult}.
* The {@code scanResult} used must contain a valid advertisingSid. First
* call to registerSync will use the {@code skip} and {@code timeout} provided.
* Subsequent calls from other apps, trying to sync with same set will reuse
* existing sync, thus {@code skip} and {@code timeout} values will not take
* effect. The values in effect will be returned in
* {@link PeriodicAdvertisingCallback#onSyncEstablished}.
*
* @param scanResult Scan result containing advertisingSid.
* @param skip The number of periodic advertising packets that can be skipped
* after a successful receive. Must be between 0 and 499.
* @param timeout Synchronization timeout for the periodic advertising. One
* unit is 10ms. Must be between 10 (100ms) and 16384 (163.84s).
* @param callback Callback used to deliver all operations status.
* @throws IllegalArgumentException if {@code scanResult} is null or {@code
* skip} is invalid or {@code timeout} is invalid or {@code callback} is null.
*/
public void registerSync(ScanResult scanResult, int skip, int timeout,
PeriodicAdvertisingCallback callback) {
registerSync(scanResult, skip, timeout, callback, null);
}
/**
* Synchronize with periodic advertising pointed to by the {@code scanResult}.
* The {@code scanResult} used must contain a valid advertisingSid. First
* call to registerSync will use the {@code skip} and {@code timeout} provided.
* Subsequent calls from other apps, trying to sync with same set will reuse
* existing sync, thus {@code skip} and {@code timeout} values will not take
* effect. The values in effect will be returned in
* {@link PeriodicAdvertisingCallback#onSyncEstablished}.
*
* @param scanResult Scan result containing advertisingSid.
* @param skip The number of periodic advertising packets that can be skipped
* after a successful receive. Must be between 0 and 499.
* @param timeout Synchronization timeout for the periodic advertising. One
* unit is 10ms. Must be between 10 (100ms) and 16384 (163.84s).
* @param callback Callback used to deliver all operations status.
* @param handler thread upon which the callbacks will be invoked.
* @throws IllegalArgumentException if {@code scanResult} is null or {@code
* skip} is invalid or {@code timeout} is invalid or {@code callback} is null.
*/
public void registerSync(ScanResult scanResult, int skip, int timeout,
PeriodicAdvertisingCallback callback, Handler handler) {
if (callback == null) {
throw new IllegalArgumentException("callback can't be null");
/**
* Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
*
* @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
* @hide
*/
public PeriodicAdvertisingManager(IBluetoothManager bluetoothManager) {
mBluetoothManager = bluetoothManager;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mCallbackWrappers = new IdentityHashMap<>();
}
if (scanResult == null) {
throw new IllegalArgumentException("scanResult can't be null");
/**
* Synchronize with periodic advertising pointed to by the {@code scanResult}.
* The {@code scanResult} used must contain a valid advertisingSid. First
* call to registerSync will use the {@code skip} and {@code timeout} provided.
* Subsequent calls from other apps, trying to sync with same set will reuse
* existing sync, thus {@code skip} and {@code timeout} values will not take
* effect. The values in effect will be returned in
* {@link PeriodicAdvertisingCallback#onSyncEstablished}.
*
* @param scanResult Scan result containing advertisingSid.
* @param skip The number of periodic advertising packets that can be skipped after a successful
* receive. Must be between 0 and 499.
* @param timeout Synchronization timeout for the periodic advertising. One unit is 10ms. Must
* be between 10 (100ms) and 16384 (163.84s).
* @param callback Callback used to deliver all operations status.
* @throws IllegalArgumentException if {@code scanResult} is null or {@code skip} is invalid or
* {@code timeout} is invalid or {@code callback} is null.
*/
public void registerSync(ScanResult scanResult, int skip, int timeout,
PeriodicAdvertisingCallback callback) {
registerSync(scanResult, skip, timeout, callback, null);
}
if (scanResult.getAdvertisingSid() == ScanResult.SID_NOT_PRESENT) {
throw new IllegalArgumentException("scanResult must contain a valid sid");
/**
* Synchronize with periodic advertising pointed to by the {@code scanResult}.
* The {@code scanResult} used must contain a valid advertisingSid. First
* call to registerSync will use the {@code skip} and {@code timeout} provided.
* Subsequent calls from other apps, trying to sync with same set will reuse
* existing sync, thus {@code skip} and {@code timeout} values will not take
* effect. The values in effect will be returned in
* {@link PeriodicAdvertisingCallback#onSyncEstablished}.
*
* @param scanResult Scan result containing advertisingSid.
* @param skip The number of periodic advertising packets that can be skipped after a successful
* receive. Must be between 0 and 499.
* @param timeout Synchronization timeout for the periodic advertising. One unit is 10ms. Must
* be between 10 (100ms) and 16384 (163.84s).
* @param callback Callback used to deliver all operations status.
* @param handler thread upon which the callbacks will be invoked.
* @throws IllegalArgumentException if {@code scanResult} is null or {@code skip} is invalid or
* {@code timeout} is invalid or {@code callback} is null.
*/
public void registerSync(ScanResult scanResult, int skip, int timeout,
PeriodicAdvertisingCallback callback, Handler handler) {
if (callback == null) {
throw new IllegalArgumentException("callback can't be null");
}
if (scanResult == null) {
throw new IllegalArgumentException("scanResult can't be null");
}
if (scanResult.getAdvertisingSid() == ScanResult.SID_NOT_PRESENT) {
throw new IllegalArgumentException("scanResult must contain a valid sid");
}
if (skip < SKIP_MIN || skip > SKIP_MAX) {
throw new IllegalArgumentException(
"timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
}
if (timeout < TIMEOUT_MIN || timeout > TIMEOUT_MAX) {
throw new IllegalArgumentException(
"timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
}
IBluetoothGatt gatt;
try {
gatt = mBluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
callback.onSyncEstablished(0, scanResult.getDevice(), scanResult.getAdvertisingSid(),
skip, timeout,
PeriodicAdvertisingCallback.SYNC_NO_RESOURCES);
return;
}
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
}
IPeriodicAdvertisingCallback wrapped = wrap(callback, handler);
mCallbackWrappers.put(callback, wrapped);
try {
gatt.registerSync(scanResult, skip, timeout, wrapped);
} catch (RemoteException e) {
Log.e(TAG, "Failed to register sync - ", e);
return;
}
}
if (skip < SKIP_MIN || skip > SKIP_MAX) {
throw new IllegalArgumentException(
"timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
/**
* Cancel pending attempt to create sync, or terminate existing sync.
*
* @param callback Callback used to deliver all operations status.
* @throws IllegalArgumentException if {@code callback} is null, or not a properly registered
* callback.
*/
public void unregisterSync(PeriodicAdvertisingCallback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback can't be null");
}
IBluetoothGatt gatt;
try {
gatt = mBluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
return;
}
IPeriodicAdvertisingCallback wrapper = mCallbackWrappers.remove(callback);
if (wrapper == null) {
throw new IllegalArgumentException("callback was not properly registered");
}
try {
gatt.unregisterSync(wrapper);
} catch (RemoteException e) {
Log.e(TAG, "Failed to cancel sync creation - ", e);
return;
}
}
if (timeout < TIMEOUT_MIN || timeout > TIMEOUT_MAX) {
throw new IllegalArgumentException(
"timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
private IPeriodicAdvertisingCallback wrap(PeriodicAdvertisingCallback callback,
Handler handler) {
return new IPeriodicAdvertisingCallback.Stub() {
public void onSyncEstablished(int syncHandle, BluetoothDevice device,
int advertisingSid, int skip, int timeout, int status) {
handler.post(new Runnable() {
@Override
public void run() {
callback.onSyncEstablished(syncHandle, device, advertisingSid, skip,
timeout,
status);
if (status != PeriodicAdvertisingCallback.SYNC_SUCCESS) {
// App can still unregister the sync until notified it failed. Remove
// callback
// after app was notifed.
mCallbackWrappers.remove(callback);
}
}
});
}
public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
handler.post(new Runnable() {
@Override
public void run() {
callback.onPeriodicAdvertisingReport(report);
}
});
}
public void onSyncLost(int syncHandle) {
handler.post(new Runnable() {
@Override
public void run() {
callback.onSyncLost(syncHandle);
// App can still unregister the sync until notified it's lost.
// Remove callback after app was notifed.
mCallbackWrappers.remove(callback);
}
});
}
};
}
IBluetoothGatt gatt;
try {
gatt = mBluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
callback.onSyncEstablished(0, scanResult.getDevice(), scanResult.getAdvertisingSid(),
skip, timeout,
PeriodicAdvertisingCallback.SYNC_NO_RESOURCES);
return;
}
if (handler == null)
handler = new Handler(Looper.getMainLooper());
IPeriodicAdvertisingCallback wrapped = wrap(callback, handler);
callbackWrappers.put(callback, wrapped);
try {
gatt.registerSync(scanResult, skip, timeout, wrapped);
} catch (RemoteException e) {
Log.e(TAG, "Failed to register sync - ", e);
return;
}
}
/**
* Cancel pending attempt to create sync, or terminate existing sync.
*
* @param callback Callback used to deliver all operations status.
* @throws IllegalArgumentException if {@code callback} is null, or not a properly
* registered callback.
*/
public void unregisterSync(PeriodicAdvertisingCallback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback can't be null");
}
IBluetoothGatt gatt;
try {
gatt = mBluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
return;
}
IPeriodicAdvertisingCallback wrapper = callbackWrappers.remove(callback);
if (wrapper == null) {
throw new IllegalArgumentException("callback was not properly registered");
}
try {
gatt.unregisterSync(wrapper);
} catch (RemoteException e) {
Log.e(TAG, "Failed to cancel sync creation - ", e);
return;
}
}
private IPeriodicAdvertisingCallback wrap(PeriodicAdvertisingCallback callback, Handler handler) {
return new IPeriodicAdvertisingCallback.Stub() {
public void onSyncEstablished(int syncHandle, BluetoothDevice device,
int advertisingSid, int skip, int timeout, int status) {
handler.post(new Runnable() {
@Override
public void run() {
callback.onSyncEstablished(syncHandle, device, advertisingSid, skip, timeout,
status);
if (status != PeriodicAdvertisingCallback.SYNC_SUCCESS) {
// App can still unregister the sync until notified it failed. Remove callback
// after app was notifed.
callbackWrappers.remove(callback);
}
}
});
}
public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
handler.post(new Runnable() {
@Override
public void run() {
callback.onPeriodicAdvertisingReport(report);
}
});
}
public void onSyncLost(int syncHandle) {
handler.post(new Runnable() {
@Override
public void run() {
callback.onSyncLost(syncHandle);
// App can still unregister the sync until notified it's lost. Remove callback after
// app was notifed.
callbackWrappers.remove(callback);
}
});
}
};
}
}

View File

@@ -29,29 +29,33 @@ public final class PeriodicAdvertisingParameters implements Parcelable {
private static final int INTERVAL_MIN = 80;
private static final int INTERVAL_MAX = 65519;
private final boolean includeTxPower;
private final int interval;
private final boolean mIncludeTxPower;
private final int mInterval;
private PeriodicAdvertisingParameters(boolean includeTxPower, int interval) {
this.includeTxPower = includeTxPower;
this.interval = interval;
mIncludeTxPower = includeTxPower;
mInterval = interval;
}
private PeriodicAdvertisingParameters(Parcel in) {
includeTxPower = in.readInt() != 0 ? true : false;
interval = in.readInt();
mIncludeTxPower = in.readInt() != 0;
mInterval = in.readInt();
}
/**
* Returns whether the TX Power will be included.
*/
public boolean getIncludeTxPower() { return includeTxPower; }
public boolean getIncludeTxPower() {
return mIncludeTxPower;
}
/**
* Returns the periodic advertising interval, in 1.25ms unit.
* Valid values are from 80 (100ms) to 65519 (81.89875s).
*/
public int getInterval() { return interval; }
public int getInterval() {
return mInterval;
}
@Override
public int describeContents() {
@@ -60,34 +64,34 @@ public final class PeriodicAdvertisingParameters implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(includeTxPower ? 1 : 0);
dest.writeInt(interval);
dest.writeInt(mIncludeTxPower ? 1 : 0);
dest.writeInt(mInterval);
}
public static final Parcelable
.Creator<PeriodicAdvertisingParameters> CREATOR =
new Creator<PeriodicAdvertisingParameters>() {
@Override
public PeriodicAdvertisingParameters[] newArray(int size) {
return new PeriodicAdvertisingParameters[size];
}
.Creator<PeriodicAdvertisingParameters> CREATOR =
new Creator<PeriodicAdvertisingParameters>() {
@Override
public PeriodicAdvertisingParameters[] newArray(int size) {
return new PeriodicAdvertisingParameters[size];
}
@Override
public PeriodicAdvertisingParameters createFromParcel(Parcel in) {
return new PeriodicAdvertisingParameters(in);
}
};
@Override
public PeriodicAdvertisingParameters createFromParcel(Parcel in) {
return new PeriodicAdvertisingParameters(in);
}
};
public static final class Builder {
private boolean includeTxPower = false;
private int interval = INTERVAL_MAX;
private boolean mIncludeTxPower = false;
private int mInterval = INTERVAL_MAX;
/**
* Whether the transmission power level should be included in the periodic
* packet.
*/
public Builder setIncludeTxPower(boolean includeTxPower) {
this.includeTxPower = includeTxPower;
mIncludeTxPower = includeTxPower;
return this;
}
@@ -95,14 +99,15 @@ public final class PeriodicAdvertisingParameters implements Parcelable {
* Set advertising interval for periodic advertising, in 1.25ms unit.
* Valid values are from 80 (100ms) to 65519 (81.89875s).
* Value from range [interval, interval+20ms] will be picked as the actual value.
*
* @throws IllegalArgumentException If the interval is invalid.
*/
public Builder setInterval(int interval) {
if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
throw new IllegalArgumentException("Invalid interval (must be " + INTERVAL_MIN +
"-" + INTERVAL_MAX + ")");
throw new IllegalArgumentException("Invalid interval (must be " + INTERVAL_MIN
+ "-" + INTERVAL_MAX + ")");
}
this.interval = interval;
mInterval = interval;
return this;
}
@@ -110,7 +115,7 @@ public final class PeriodicAdvertisingParameters implements Parcelable {
* Build the {@link AdvertisingSetParameters} object.
*/
public PeriodicAdvertisingParameters build() {
return new PeriodicAdvertisingParameters(includeTxPower, interval);
return new PeriodicAdvertisingParameters(mIncludeTxPower, mInterval);
}
}
}

View File

@@ -24,6 +24,7 @@ import java.util.Objects;
/**
* PeriodicAdvertisingReport for Bluetooth LE synchronized advertising.
*
* @hide
*/
public final class PeriodicAdvertisingReport implements Parcelable {
@@ -39,29 +40,28 @@ public final class PeriodicAdvertisingReport implements Parcelable {
*/
public static final int DATA_INCOMPLETE_TRUNCATED = 2;
private int syncHandle;
private int txPower;
private int rssi;
private int dataStatus;
private int mSyncHandle;
private int mTxPower;
private int mRssi;
private int mDataStatus;
// periodic advertising data.
@Nullable
private ScanRecord data;
private ScanRecord mData;
// Device timestamp when the result was last seen.
private long timestampNanos;
private long mTimestampNanos;
/**
* Constructor of periodic advertising result.
*
*/
public PeriodicAdvertisingReport(int syncHandle, int txPower, int rssi,
int dataStatus, ScanRecord data) {
this.syncHandle = syncHandle;
this.txPower = txPower;
this.rssi = rssi;
this.dataStatus = dataStatus;
this.data = data;
int dataStatus, ScanRecord data) {
mSyncHandle = syncHandle;
mTxPower = txPower;
mRssi = rssi;
mDataStatus = dataStatus;
mData = data;
}
private PeriodicAdvertisingReport(Parcel in) {
@@ -70,25 +70,25 @@ public final class PeriodicAdvertisingReport implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(syncHandle);
dest.writeLong(txPower);
dest.writeInt(rssi);
dest.writeInt(dataStatus);
if (data != null) {
dest.writeInt(mSyncHandle);
dest.writeLong(mTxPower);
dest.writeInt(mRssi);
dest.writeInt(mDataStatus);
if (mData != null) {
dest.writeInt(1);
dest.writeByteArray(data.getBytes());
dest.writeByteArray(mData.getBytes());
} else {
dest.writeInt(0);
}
}
private void readFromParcel(Parcel in) {
syncHandle = in.readInt();
txPower = in.readInt();
rssi = in.readInt();
dataStatus = in.readInt();
mSyncHandle = in.readInt();
mTxPower = in.readInt();
mRssi = in.readInt();
mDataStatus = in.readInt();
if (in.readInt() == 1) {
data = ScanRecord.parseFromBytes(in.createByteArray());
mData = ScanRecord.parseFromBytes(in.createByteArray());
}
}
@@ -101,7 +101,7 @@ public final class PeriodicAdvertisingReport implements Parcelable {
* Returns the synchronization handle.
*/
public int getSyncHandle() {
return syncHandle;
return mSyncHandle;
}
/**
@@ -109,14 +109,14 @@ public final class PeriodicAdvertisingReport implements Parcelable {
* of 127 means information was not available.
*/
public int getTxPower() {
return txPower;
return mTxPower;
}
/**
* Returns the received signal strength in dBm. The valid range is [-127, 20].
*/
public int getRssi() {
return rssi;
return mRssi;
}
/**
@@ -124,7 +124,7 @@ public final class PeriodicAdvertisingReport implements Parcelable {
* or {@link PeriodicAdvertisingReport#DATA_INCOMPLETE_TRUNCATED}.
*/
public int getDataStatus() {
return dataStatus;
return mDataStatus;
}
/**
@@ -132,19 +132,19 @@ public final class PeriodicAdvertisingReport implements Parcelable {
*/
@Nullable
public ScanRecord getData() {
return data;
return mData;
}
/**
* Returns timestamp since boot when the scan record was observed.
*/
public long getTimestampNanos() {
return timestampNanos;
return mTimestampNanos;
}
@Override
public int hashCode() {
return Objects.hash(syncHandle, txPower, rssi, dataStatus, data, timestampNanos);
return Objects.hash(mSyncHandle, mTxPower, mRssi, mDataStatus, mData, mTimestampNanos);
}
@Override
@@ -156,30 +156,31 @@ public final class PeriodicAdvertisingReport implements Parcelable {
return false;
}
PeriodicAdvertisingReport other = (PeriodicAdvertisingReport) obj;
return (syncHandle == other.syncHandle) &&
(txPower == other.txPower) &&
(rssi == other.rssi) &&
(dataStatus == other.dataStatus) &&
Objects.equals(data, other.data) &&
(timestampNanos == other.timestampNanos);
return (mSyncHandle == other.mSyncHandle)
&& (mTxPower == other.mTxPower)
&& (mRssi == other.mRssi)
&& (mDataStatus == other.mDataStatus)
&& Objects.equals(mData, other.mData)
&& (mTimestampNanos == other.mTimestampNanos);
}
@Override
public String toString() {
return "PeriodicAdvertisingReport{syncHandle=" + syncHandle +
", txPower=" + txPower + ", rssi=" + rssi + ", dataStatus=" + dataStatus +
", data=" + Objects.toString(data) + ", timestampNanos=" + timestampNanos + '}';
return "PeriodicAdvertisingReport{syncHandle=" + mSyncHandle
+ ", txPower=" + mTxPower + ", rssi=" + mRssi + ", dataStatus=" + mDataStatus
+ ", data=" + Objects.toString(mData) + ", timestampNanos=" + mTimestampNanos + '}';
}
public static final Parcelable.Creator<PeriodicAdvertisingReport> CREATOR = new Creator<PeriodicAdvertisingReport>() {
@Override
public PeriodicAdvertisingReport createFromParcel(Parcel source) {
return new PeriodicAdvertisingReport(source);
}
public static final Parcelable.Creator<PeriodicAdvertisingReport> CREATOR =
new Creator<PeriodicAdvertisingReport>() {
@Override
public PeriodicAdvertisingReport createFromParcel(Parcel source) {
return new PeriodicAdvertisingReport(source);
}
@Override
public PeriodicAdvertisingReport[] newArray(int size) {
return new PeriodicAdvertisingReport[size];
}
};
@Override
public PeriodicAdvertisingReport[] newArray(int size) {
return new PeriodicAdvertisingReport[size];
}
};
}

View File

@@ -78,16 +78,16 @@ public final class ResultStorageDescriptor implements Parcelable {
mLength = in.readInt();
}
public static final Parcelable.Creator<ResultStorageDescriptor>
CREATOR = new Creator<ResultStorageDescriptor>() {
@Override
public ResultStorageDescriptor createFromParcel(Parcel source) {
return new ResultStorageDescriptor(source);
}
public static final Parcelable.Creator<ResultStorageDescriptor> CREATOR =
new Creator<ResultStorageDescriptor>() {
@Override
public ResultStorageDescriptor createFromParcel(Parcel source) {
return new ResultStorageDescriptor(source);
}
@Override
public ResultStorageDescriptor[] newArray(int size) {
return new ResultStorageDescriptor[size];
}
};
@Override
public ResultStorageDescriptor[] newArray(int size) {
return new ResultStorageDescriptor[size];
}
};
}

View File

@@ -46,6 +46,7 @@ public abstract class ScanCallback {
/**
* Fails to start scan as it is out of hardware resources.
*
* @hide
*/
public static final int SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES = 5;
@@ -55,10 +56,9 @@ public abstract class ScanCallback {
/**
* Callback when a BLE advertisement has been found.
*
* @param callbackType Determines how this callback was triggered. Could be one of
* {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES},
* {@link ScanSettings#CALLBACK_TYPE_FIRST_MATCH} or
* {@link ScanSettings#CALLBACK_TYPE_MATCH_LOST}
* @param callbackType Determines how this callback was triggered. Could be one of {@link
* ScanSettings#CALLBACK_TYPE_ALL_MATCHES}, {@link ScanSettings#CALLBACK_TYPE_FIRST_MATCH} or
* {@link ScanSettings#CALLBACK_TYPE_MATCH_LOST}
* @param result A Bluetooth LE scan result.
*/
public void onScanResult(int callbackType, ScanResult result) {

View File

@@ -71,7 +71,7 @@ public final class ScanFilter implements Parcelable {
private final byte[] mManufacturerDataMask;
/** @hide */
public static final ScanFilter EMPTY = new ScanFilter.Builder().build() ;
public static final ScanFilter EMPTY = new ScanFilter.Builder().build();
private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
@@ -145,70 +145,70 @@ public final class ScanFilter implements Parcelable {
/**
* A {@link android.os.Parcelable.Creator} to create {@link ScanFilter} from parcel.
*/
public static final Creator<ScanFilter>
CREATOR = new Creator<ScanFilter>() {
public static final Creator<ScanFilter> CREATOR =
new Creator<ScanFilter>() {
@Override
public ScanFilter[] newArray(int size) {
return new ScanFilter[size];
@Override
public ScanFilter[] newArray(int size) {
return new ScanFilter[size];
}
@Override
public ScanFilter createFromParcel(Parcel in) {
Builder builder = new Builder();
if (in.readInt() == 1) {
builder.setDeviceName(in.readString());
}
if (in.readInt() == 1) {
builder.setDeviceAddress(in.readString());
}
if (in.readInt() == 1) {
ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader());
builder.setServiceUuid(uuid);
if (in.readInt() == 1) {
ParcelUuid uuidMask = in.readParcelable(
ParcelUuid.class.getClassLoader());
builder.setServiceUuid(uuid, uuidMask);
}
@Override
public ScanFilter createFromParcel(Parcel in) {
Builder builder = new Builder();
if (in.readInt() == 1) {
builder.setDeviceName(in.readString());
}
if (in.readInt() == 1) {
ParcelUuid servcieDataUuid =
in.readParcelable(ParcelUuid.class.getClassLoader());
if (in.readInt() == 1) {
int serviceDataLength = in.readInt();
byte[] serviceData = new byte[serviceDataLength];
in.readByteArray(serviceData);
if (in.readInt() == 0) {
builder.setServiceData(servcieDataUuid, serviceData);
} else {
int serviceDataMaskLength = in.readInt();
byte[] serviceDataMask = new byte[serviceDataMaskLength];
in.readByteArray(serviceDataMask);
builder.setServiceData(
servcieDataUuid, serviceData, serviceDataMask);
}
if (in.readInt() == 1) {
builder.setDeviceAddress(in.readString());
}
if (in.readInt() == 1) {
ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader());
builder.setServiceUuid(uuid);
if (in.readInt() == 1) {
ParcelUuid uuidMask = in.readParcelable(
ParcelUuid.class.getClassLoader());
builder.setServiceUuid(uuid, uuidMask);
}
}
if (in.readInt() == 1) {
ParcelUuid servcieDataUuid =
in.readParcelable(ParcelUuid.class.getClassLoader());
if (in.readInt() == 1) {
int serviceDataLength = in.readInt();
byte[] serviceData = new byte[serviceDataLength];
in.readByteArray(serviceData);
if (in.readInt() == 0) {
builder.setServiceData(servcieDataUuid, serviceData);
} else {
int serviceDataMaskLength = in.readInt();
byte[] serviceDataMask = new byte[serviceDataMaskLength];
in.readByteArray(serviceDataMask);
builder.setServiceData(
servcieDataUuid, serviceData, serviceDataMask);
}
}
}
int manufacturerId = in.readInt();
if (in.readInt() == 1) {
int manufacturerDataLength = in.readInt();
byte[] manufacturerData = new byte[manufacturerDataLength];
in.readByteArray(manufacturerData);
if (in.readInt() == 0) {
builder.setManufacturerData(manufacturerId, manufacturerData);
} else {
int manufacturerDataMaskLength = in.readInt();
byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength];
in.readByteArray(manufacturerDataMask);
builder.setManufacturerData(manufacturerId, manufacturerData,
manufacturerDataMask);
}
}
return builder.build();
}
};
}
int manufacturerId = in.readInt();
if (in.readInt() == 1) {
int manufacturerDataLength = in.readInt();
byte[] manufacturerData = new byte[manufacturerDataLength];
in.readByteArray(manufacturerData);
if (in.readInt() == 0) {
builder.setManufacturerData(manufacturerId, manufacturerData);
} else {
int manufacturerDataMaskLength = in.readInt();
byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength];
in.readByteArray(manufacturerDataMask);
builder.setManufacturerData(manufacturerId, manufacturerData,
manufacturerDataMask);
}
}
return builder.build();
}
};
/**
* Returns the filter set the device name field of Bluetooth advertisement data.
@@ -288,7 +288,7 @@ public final class ScanFilter implements Parcelable {
// Scan record is null but there exist filters on it.
if (scanRecord == null
&& (mDeviceName != null || mServiceUuid != null || mManufacturerData != null
|| mServiceData != null)) {
|| mServiceData != null)) {
return false;
}
@@ -386,12 +386,12 @@ public final class ScanFilter implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mDeviceName, mDeviceAddress, mManufacturerId,
Arrays.hashCode(mManufacturerData),
Arrays.hashCode(mManufacturerDataMask),
mServiceDataUuid,
Arrays.hashCode(mServiceData),
Arrays.hashCode(mServiceDataMask),
mServiceUuid, mServiceUuidMask);
Arrays.hashCode(mManufacturerData),
Arrays.hashCode(mManufacturerDataMask),
mServiceDataUuid,
Arrays.hashCode(mServiceData),
Arrays.hashCode(mServiceDataMask),
mServiceUuid, mServiceUuidMask);
}
@Override
@@ -403,20 +403,21 @@ public final class ScanFilter implements Parcelable {
return false;
}
ScanFilter other = (ScanFilter) obj;
return Objects.equals(mDeviceName, other.mDeviceName) &&
Objects.equals(mDeviceAddress, other.mDeviceAddress) &&
mManufacturerId == other.mManufacturerId &&
Objects.deepEquals(mManufacturerData, other.mManufacturerData) &&
Objects.deepEquals(mManufacturerDataMask, other.mManufacturerDataMask) &&
Objects.equals(mServiceDataUuid, other.mServiceDataUuid) &&
Objects.deepEquals(mServiceData, other.mServiceData) &&
Objects.deepEquals(mServiceDataMask, other.mServiceDataMask) &&
Objects.equals(mServiceUuid, other.mServiceUuid) &&
Objects.equals(mServiceUuidMask, other.mServiceUuidMask);
return Objects.equals(mDeviceName, other.mDeviceName)
&& Objects.equals(mDeviceAddress, other.mDeviceAddress)
&& mManufacturerId == other.mManufacturerId
&& Objects.deepEquals(mManufacturerData, other.mManufacturerData)
&& Objects.deepEquals(mManufacturerDataMask, other.mManufacturerDataMask)
&& Objects.equals(mServiceDataUuid, other.mServiceDataUuid)
&& Objects.deepEquals(mServiceData, other.mServiceData)
&& Objects.deepEquals(mServiceDataMask, other.mServiceDataMask)
&& Objects.equals(mServiceUuid, other.mServiceUuid)
&& Objects.equals(mServiceUuidMask, other.mServiceUuidMask);
}
/**
* Checks if the scanfilter is empty
*
* @hide
*/
public boolean isAllFieldsEmpty() {
@@ -454,8 +455,8 @@ public final class ScanFilter implements Parcelable {
* Set filter on device address.
*
* @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
* format of "01:02:03:AB:CD:EF". The device address can be validated using
* {@link BluetoothAdapter#checkBluetoothAddress}.
* format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
* BluetoothAdapter#checkBluetoothAddress}.
* @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
*/
public Builder setDeviceAddress(String deviceAddress) {
@@ -480,8 +481,8 @@ public final class ScanFilter implements Parcelable {
* {@code serviceUuid}. Set any bit in the mask to 1 to indicate a match is needed for the
* bit in {@code serviceUuid}, and 0 to ignore that bit.
*
* @throws IllegalArgumentException If {@code serviceUuid} is {@code null} but
* {@code uuidMask} is not {@code null}.
* @throws IllegalArgumentException If {@code serviceUuid} is {@code null} but {@code
* uuidMask} is not {@code null}.
*/
public Builder setServiceUuid(ParcelUuid serviceUuid, ParcelUuid uuidMask) {
if (mUuidMask != null && mServiceUuid == null) {
@@ -513,9 +514,9 @@ public final class ScanFilter implements Parcelable {
* <p>
* The {@code serviceDataMask} must have the same length of the {@code serviceData}.
*
* @throws IllegalArgumentException If {@code serviceDataUuid} is null or
* {@code serviceDataMask} is {@code null} while {@code serviceData} is not or
* {@code serviceDataMask} and {@code serviceData} has different length.
* @throws IllegalArgumentException If {@code serviceDataUuid} is null or {@code
* serviceDataMask} is {@code null} while {@code serviceData} is not or {@code
* serviceDataMask} and {@code serviceData} has different length.
*/
public Builder setServiceData(ParcelUuid serviceDataUuid,
byte[] serviceData, byte[] serviceDataMask) {
@@ -563,10 +564,9 @@ public final class ScanFilter implements Parcelable {
* <p>
* The {@code manufacturerDataMask} must have the same length of {@code manufacturerData}.
*
* @throws IllegalArgumentException If the {@code manufacturerId} is invalid, or
* {@code manufacturerData} is null while {@code manufacturerDataMask} is not,
* or {@code manufacturerData} and {@code manufacturerDataMask} have different
* length.
* @throws IllegalArgumentException If the {@code manufacturerId} is invalid, or {@code
* manufacturerData} is null while {@code manufacturerDataMask} is not, or {@code
* manufacturerData} and {@code manufacturerDataMask} have different length.
*/
public Builder setManufacturerData(int manufacturerId, byte[] manufacturerData,
byte[] manufacturerDataMask) {

View File

@@ -231,9 +231,9 @@ public final class ScanRecord {
case DATA_TYPE_SERVICE_DATA_128_BIT:
int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
if (fieldType == DATA_TYPE_SERVICE_DATA_32_BIT) {
serviceUuidLength = BluetoothUuid.UUID_BYTES_32_BIT;
serviceUuidLength = BluetoothUuid.UUID_BYTES_32_BIT;
} else if (fieldType == DATA_TYPE_SERVICE_DATA_128_BIT) {
serviceUuidLength = BluetoothUuid.UUID_BYTES_128_BIT;
serviceUuidLength = BluetoothUuid.UUID_BYTES_128_BIT;
}
byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
@@ -247,8 +247,8 @@ public final class ScanRecord {
case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
// The first two bytes of the manufacturer specific data are
// manufacturer ids in little endian.
int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) +
(scanRecord[currentPos] & 0xFF);
int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8)
+ (scanRecord[currentPos] & 0xFF);
byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
dataLength - 2);
manufacturerData.put(manufacturerId, manufacturerDataBytes);
@@ -276,7 +276,8 @@ public final class ScanRecord {
@Override
public String toString() {
return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
+ ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(mManufacturerSpecificData)
+ ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
mManufacturerSpecificData)
+ ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
+ ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
}

View File

@@ -98,8 +98,10 @@ public final class ScanResult implements Parcelable {
* @param scanRecord Scan record including both advertising data and scan response data.
* @param rssi Received signal strength.
* @param timestampNanos Timestamp at which the scan result was observed.
* @deprecated use {@link #ScanResult(BluetoothDevice, int, int, int, int, int, int, int, ScanRecord, long)}
* @deprecated use {@link #ScanResult(BluetoothDevice, int, int, int, int, int, int, int,
* ScanRecord, long)}
*/
@Deprecated
public ScanResult(BluetoothDevice device, ScanRecord scanRecord, int rssi,
long timestampNanos) {
mDevice = device;
@@ -129,8 +131,8 @@ public final class ScanResult implements Parcelable {
* @param timestampNanos Timestamp at which the scan result was observed.
*/
public ScanResult(BluetoothDevice device, int eventType, int primaryPhy, int secondaryPhy,
int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
ScanRecord scanRecord, long timestampNanos) {
int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
ScanRecord scanRecord, long timestampNanos) {
mDevice = device;
mEventType = eventType;
mPrimaryPhy = primaryPhy;
@@ -254,7 +256,9 @@ public final class ScanResult implements Parcelable {
* Can be one of {@link BluetoothDevice#PHY_LE_1M} or
* {@link BluetoothDevice#PHY_LE_CODED}.
*/
public int getPrimaryPhy() { return mPrimaryPhy; }
public int getPrimaryPhy() {
return mPrimaryPhy;
}
/**
* Returns the secondary Physical Layer
@@ -264,21 +268,27 @@ public final class ScanResult implements Parcelable {
* or {@link ScanResult#PHY_UNUSED} - if the advertisement
* was not received on a secondary physical channel.
*/
public int getSecondaryPhy() { return mSecondaryPhy; }
public int getSecondaryPhy() {
return mSecondaryPhy;
}
/**
* Returns the advertising set id.
* May return {@link ScanResult#SID_NOT_PRESENT} if
* no set id was is present.
*/
public int getAdvertisingSid() { return mAdvertisingSid; }
public int getAdvertisingSid() {
return mAdvertisingSid;
}
/**
* Returns the transmit power in dBm.
* Valid range is [-127, 126]. A value of {@link ScanResult#TX_POWER_NOT_PRESENT}
* indicates that the TX power is not present.
*/
public int getTxPower() { return mTxPower; }
public int getTxPower() {
return mTxPower;
}
/**
* Returns the periodic advertising interval in units of 1.25ms.
@@ -293,9 +303,9 @@ public final class ScanResult implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mDevice, mRssi, mScanRecord, mTimestampNanos,
mEventType, mPrimaryPhy, mSecondaryPhy,
mAdvertisingSid, mTxPower,
mPeriodicAdvertisingInterval);
mEventType, mPrimaryPhy, mSecondaryPhy,
mAdvertisingSid, mTxPower,
mPeriodicAdvertisingInterval);
}
@Override
@@ -307,34 +317,34 @@ public final class ScanResult implements Parcelable {
return false;
}
ScanResult other = (ScanResult) obj;
return Objects.equals(mDevice, other.mDevice) && (mRssi == other.mRssi) &&
Objects.equals(mScanRecord, other.mScanRecord) &&
(mTimestampNanos == other.mTimestampNanos) &&
mEventType == other.mEventType &&
mPrimaryPhy == other.mPrimaryPhy &&
mSecondaryPhy == other.mSecondaryPhy &&
mAdvertisingSid == other.mAdvertisingSid &&
mTxPower == other.mTxPower &&
mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
return Objects.equals(mDevice, other.mDevice) && (mRssi == other.mRssi)
&& Objects.equals(mScanRecord, other.mScanRecord)
&& (mTimestampNanos == other.mTimestampNanos)
&& mEventType == other.mEventType
&& mPrimaryPhy == other.mPrimaryPhy
&& mSecondaryPhy == other.mSecondaryPhy
&& mAdvertisingSid == other.mAdvertisingSid
&& mTxPower == other.mTxPower
&& mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
}
@Override
public String toString() {
return "ScanResult{" + "device=" + mDevice + ", scanRecord=" +
Objects.toString(mScanRecord) + ", rssi=" + mRssi +
", timestampNanos=" + mTimestampNanos + ", eventType=" + mEventType +
", primaryPhy=" + mPrimaryPhy + ", secondaryPhy=" + mSecondaryPhy +
", advertisingSid=" + mAdvertisingSid + ", txPower=" + mTxPower +
", periodicAdvertisingInterval=" + mPeriodicAdvertisingInterval + '}';
return "ScanResult{" + "device=" + mDevice + ", scanRecord="
+ Objects.toString(mScanRecord) + ", rssi=" + mRssi
+ ", timestampNanos=" + mTimestampNanos + ", eventType=" + mEventType
+ ", primaryPhy=" + mPrimaryPhy + ", secondaryPhy=" + mSecondaryPhy
+ ", advertisingSid=" + mAdvertisingSid + ", txPower=" + mTxPower
+ ", periodicAdvertisingInterval=" + mPeriodicAdvertisingInterval + '}';
}
public static final Parcelable.Creator<ScanResult> CREATOR = new Creator<ScanResult>() {
@Override
@Override
public ScanResult createFromParcel(Parcel source) {
return new ScanResult(source);
}
@Override
@Override
public ScanResult[] newArray(int size) {
return new ScanResult[size];
}

View File

@@ -202,8 +202,8 @@ public final class ScanSettings implements Parcelable {
}
private ScanSettings(int scanMode, int callbackType, int scanResultType,
long reportDelayMillis, int matchMode,
int numOfMatchesPerFilter, boolean legacy, int phy) {
long reportDelayMillis, int matchMode,
int numOfMatchesPerFilter, boolean legacy, int phy) {
mScanMode = scanMode;
mCallbackType = callbackType;
mScanResultType = scanResultType;
@@ -221,7 +221,7 @@ public final class ScanSettings implements Parcelable {
mReportDelayMillis = in.readLong();
mMatchMode = in.readInt();
mNumOfMatchesPerFilter = in.readInt();
mLegacy = in.readInt() != 0 ? true : false;
mLegacy = in.readInt() != 0;
mPhy = in.readInt();
}
@@ -242,18 +242,18 @@ public final class ScanSettings implements Parcelable {
return 0;
}
public static final Parcelable.Creator<ScanSettings>
CREATOR = new Creator<ScanSettings>() {
@Override
public ScanSettings[] newArray(int size) {
return new ScanSettings[size];
}
public static final Parcelable.Creator<ScanSettings> CREATOR =
new Creator<ScanSettings>() {
@Override
public ScanSettings[] newArray(int size) {
return new ScanSettings[size];
}
@Override
public ScanSettings createFromParcel(Parcel in) {
return new ScanSettings(in);
}
};
@Override
public ScanSettings createFromParcel(Parcel in) {
return new ScanSettings(in);
}
};
/**
* Builder for {@link ScanSettings}.
@@ -264,7 +264,7 @@ public final class ScanSettings implements Parcelable {
private int mScanResultType = SCAN_RESULT_TYPE_FULL;
private long mReportDelayMillis = 0;
private int mMatchMode = MATCH_MODE_AGGRESSIVE;
private int mNumOfMatchesPerFilter = MATCH_NUM_MAX_ADVERTISEMENT;
private int mNumOfMatchesPerFilter = MATCH_NUM_MAX_ADVERTISEMENT;
private boolean mLegacy = true;
private int mPhy = PHY_LE_ALL_SUPPORTED;
@@ -272,8 +272,7 @@ public final class ScanSettings implements Parcelable {
* Set scan mode for Bluetooth LE scan.
*
* @param scanMode The scan mode can be one of {@link ScanSettings#SCAN_MODE_LOW_POWER},
* {@link ScanSettings#SCAN_MODE_BALANCED} or
* {@link ScanSettings#SCAN_MODE_LOW_LATENCY}.
* {@link ScanSettings#SCAN_MODE_BALANCED} or {@link ScanSettings#SCAN_MODE_LOW_LATENCY}.
* @throws IllegalArgumentException If the {@code scanMode} is invalid.
*/
public Builder setScanMode(int scanMode) {
@@ -301,9 +300,9 @@ public final class ScanSettings implements Parcelable {
// Returns true if the callbackType is valid.
private boolean isValidCallbackType(int callbackType) {
if (callbackType == CALLBACK_TYPE_ALL_MATCHES ||
callbackType == CALLBACK_TYPE_FIRST_MATCH ||
callbackType == CALLBACK_TYPE_MATCH_LOST) {
if (callbackType == CALLBACK_TYPE_ALL_MATCHES
|| callbackType == CALLBACK_TYPE_FIRST_MATCH
|| callbackType == CALLBACK_TYPE_MATCH_LOST) {
return true;
}
return callbackType == (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST);
@@ -312,9 +311,8 @@ public final class ScanSettings implements Parcelable {
/**
* Set scan result type for Bluetooth LE scan.
*
* @param scanResultType Type for scan result, could be either
* {@link ScanSettings#SCAN_RESULT_TYPE_FULL} or
* {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}.
* @param scanResultType Type for scan result, could be either {@link
* ScanSettings#SCAN_RESULT_TYPE_FULL} or {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}.
* @throws IllegalArgumentException If the {@code scanResultType} is invalid.
* @hide
*/
@@ -333,8 +331,8 @@ public final class ScanSettings implements Parcelable {
* Set report delay timestamp for Bluetooth LE scan.
*
* @param reportDelayMillis Delay of report in milliseconds. Set to 0 to be notified of
* results immediately. Values &gt; 0 causes the scan results to be queued up and
* delivered after the requested delay or when the internal buffers fill up.
* results immediately. Values &gt; 0 causes the scan results to be queued up and delivered
* after the requested delay or when the internal buffers fill up.
* @throws IllegalArgumentException If {@code reportDelayMillis} &lt; 0.
*/
public Builder setReportDelay(long reportDelayMillis) {
@@ -349,9 +347,9 @@ public final class ScanSettings implements Parcelable {
* Set the number of matches for Bluetooth LE scan filters hardware match
*
* @param numOfMatches The num of matches can be one of
* {@link ScanSettings#MATCH_NUM_ONE_ADVERTISEMENT} or
* {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or
* {@link ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
* {@link ScanSettings#MATCH_NUM_ONE_ADVERTISEMENT}
* or {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or {@link
* ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
* @throws IllegalArgumentException If the {@code matchMode} is invalid.
*/
public Builder setNumOfMatches(int numOfMatches) {
@@ -366,9 +364,8 @@ public final class ScanSettings implements Parcelable {
/**
* Set match mode for Bluetooth LE scan filters hardware match
*
* @param matchMode The match mode can be one of
* {@link ScanSettings#MATCH_MODE_AGGRESSIVE} or
* {@link ScanSettings#MATCH_MODE_STICKY}
* @param matchMode The match mode can be one of {@link ScanSettings#MATCH_MODE_AGGRESSIVE}
* or {@link ScanSettings#MATCH_MODE_STICKY}
* @throws IllegalArgumentException If the {@code matchMode} is invalid.
*/
public Builder setMatchMode(int matchMode) {
@@ -402,10 +399,8 @@ public final class ScanSettings implements Parcelable {
* {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}.
* Selecting an unsupported phy will result in failure to start scan.
*
* @param phy Can be one of
* {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_CODED} or
* {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
* @param phy Can be one of {@link BluetoothDevice#PHY_LE_1M}, {@link
* BluetoothDevice#PHY_LE_CODED} or {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
*/
public Builder setPhy(int phy) {
mPhy = phy;
@@ -417,8 +412,8 @@ public final class ScanSettings implements Parcelable {
*/
public ScanSettings build() {
return new ScanSettings(mScanMode, mCallbackType, mScanResultType,
mReportDelayMillis, mMatchMode,
mNumOfMatchesPerFilter, mLegacy, mPhy);
mReportDelayMillis, mMatchMode,
mNumOfMatchesPerFilter, mLegacy, mPhy);
}
}
}

View File

@@ -17,6 +17,7 @@
package android.bluetooth.le;
import android.annotation.SystemApi;
import java.util.List;
/**