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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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="
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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>() {
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 + "]";
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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 > 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 > 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} < 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.bluetooth.le;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user